I'm working with the WPF DataGrid and .Net 4.5 and I'm trying to roll my own data virtualization container for a large collection. I've been all over the web and found many helpful examples of how to implement data virtualization, but in every example I've seen, the savings are lost if you do any grouping. My grouping is simple and static. Is there a way to fake grouping in WPF in such a way that my collection doesn't have to enumerate all items ahead of time? For example, has anyone ever overridden the ListCollectionView's GetItemAt() and just returned a CollectionViewGroup object at the start of each group?
Concrete Example:
Say for example I have a database with 100K records. I want to create a data virtualization collection similar to Bea Stollnitz' example and use it in a WPF DataGrid.
I want to group items in the DataGrid on a field, but I can do that by modifying my database query to first return all items in group A, then all items of group B. Grouping is done before the DataTable even sees it.
How do I visually represent the grouping inside the WPF DataGrid even though my collection (from the DataGrid's perspective) is flat? The only way I've found to show grouping in a DataGrid is by using a CollectionView or similar.
.
If you are dealing with a flat list and a static grouped list and are worried about performance related to the aggregation, I would consider storing both versions of the data sets in an index and just grab whichever one you need for each particular case.
Related
I have a ICollectionView which serves as an input source for a WPF ListView. The number of items (text messages) in the CollectionView could be upto 10 thousands. I want to add a sorting creiteria to the collection view based on the TimeStamp. The latest added message should be on top.
MyCollectionView.SortDescriptions.Add(new SortDescription("TimeStamp", ListSortDirection.Descending));
Question: If I use the above sorting criterion, does the sorting takes place every time I add a new message? Or does the CollectionView maintains a sorted list internally and in my scenerio (i.e. having TimeStamp as Sorting), it will only need to compare the new incoming message's TimeStamp with the last added message's TimeStamp?
You'd do better NOT relying on collectionview sorting and NOT presenting 10,000 items to a listview.
The answer:
By default, when you’re using a CollectionView(Source) to do sorting, grouping and filtering in an itemscontrol, the sorting/grouping/filtering behavior will update when you explicitly refresh CollectionView or
when you add or remove an item to the collection.
You should therefore not sort the collection. I think your best bet is likely to instead insert at position zero of an un sorted observablecollection.
If you're inserting lots of items quickly then that's still going to burn through cycles. These are on your UI thread so you best not plan on anyone trying to interact with your UI. If these messages come in fast enough you will just have a blur anyhow.
I think you should probably instead only show the user the latest few messages in a "live" view. Don't let them sort.
If they need to see 10,000 then put that in another view that shows them a static snapshot. See what your performance is like and think about iterating when you have something concrete to play round with.
I have a DataGrid, where I am displaying some Job data. One of the field is calculated based on 2 columns.
There is a calculated field StaffName that comes from different properties (which are hidden in data grid).
I want to sort StaffName based on the content displayed on grid, and not based on underlying property on which Converter is applied. there are actually multiple underlying properties, and handling sorting of these is complex.
The data structure comes from some other assembly which is not aware of any converters/lookups which transform different property into StaffName.
How to achieve this?
You need to capture the sort event and do the Sort the itemcollection based on your need and Assign the newly sorted collection to the ItemSource .
Following Link shows how to sort.
Check the sample
In the example it is normal sorting, at Places LINQ queries used you need to write your own LINQ query involving the fields you want to use in the orderby clause
My problem is the following: I got a Tree which has an dynamic depth of categories (each category can have sub-categories as well as entries).
Now I added a HierarchicalDataTemplate for the categories to display correctly in the TreeView. But I get a lot of empty entries, which do not apply the Template (wrong type) but show up in the tree as 'corpse'.
How can I ban them from the generation process? Because it's an abstract tree, they are of the same base-class as the categories are. So they get into the tree, because the tree always searches the "Branches"-property which contains either categories, entries or both.
Any ideas? I didn't find any event of the TreeView which probably give me the opportunity to skip various entries during generation nor any option/property of the template to do so.
Detailed Description: I got a generic Tree class. This class has branches of type "A_TreeLeaf" (abstract). The Tree's generic type must inherit A_TreeLeaf of course. My data is structured in categories (CategoryTreeLeaf) and Data (DataTreeLeaf). Each leaf can have sub-leaves (branches), of course.
Now I load my data from a database and build the tree. Each category has X sub-categories. And each category also could contain some Data. This structure helps me a lot, because I got an clear hierarchic structure of categories and data. This way it should be visualized to the user. But I want to separate Data and Categories. The TreeView should show just the categories (by an HierarchicalDataTemplate) and the ListView just the Data (by an DataTemplate). The ListView works fine, but the Tree shows some "corpse"-entries which are the DataTreeLeaf-instances.
I want to filter the DataTreeLeafs on generation or just stop the TreeView displaying them. Is there any "non-hack" solution? I don't want to copy the tree and remove the Data-leaves unless it's really necessary... because this would cause a lot of overhead work to do for me and to manage either the code behind which uses the real tree or the visualization with the fake-tree (because I need to bridge it somehow that it's updated automatically when one of both changes).
You have a unique problem... you have some data items in your hierarchical data that you don't want to display, but for some reason can't remove. If that sums up your problem, then you're doing something wrong.
In WPF, you shouldn't need to hide data items from the UI, instead you simply don't put them into the collection in the first place. It sounds like your process of filling your hierarchical data is flawed and you'd be better off fixing that at the source than trying to deal with the problems that it causes in the UI.
If you can't fix the actual process for whatever reason, then your next best option is to iterate through the data before you display it and simply remove any data elements that shouldn't be there. When using WPF, it is always best to provide your UI with data that fits the purpose.
However, if for whatever reason you can't even do that, then your last option is to simply define an additional DataTemplate for your abstract base class and just leave it empty:
<DataTemplate DataType="{x:Type YourDataTypesPrefix:YourBaseClass}">
</DataTemplate>
Of course, you'd have to define DataTemplates for each sub type, or they'd also be rendered empty.
I have a datagridviewComboBoxColumn. I want each of its cells to have as possible values a subset of a bindinglist (let's call it the "master" bindinglist).
One suggestion I found online was this: https://stackoverflow.com/a/14820929
But the items in the original bindinglist will be constantly changing (new items added, old ones removed). Is there any way to make the cells' items be automatically updated when the "master" binding list is changed?
You could see if a FilteredObservableCollection fits your needs. It's really for WPF but you could take the concept and adapt it for BindingLists.
You can have as many filtered wrappers as you want around a single master list and each one acts like a separate list, operating (and notifiying) only on the subset that matches a filter you supply.
C#: What is the best way to implement a 'filter' mechanism for ListView Items?
I want to filter out some listview items from view in 'details' mode where it contains rows and columns. What would be the best option to create such a mechanism where I could rapidly remove the items in question from view, leaving the others intact, and putting them back into the listview when there is no more need to filter out listview items? Should I remove/copy them to a List and just and add them back when done or would there be a better method of doing this more effeciently? The listview will be handeling about 100-500 items.
If you are working with a databound control you will have this facility within the binding framework.
If not, I would probably store all the items for the list separately and populate the control in full each time, based on any contextual requirements such as filtering. The code to iterate through the list and move items not required at present is probably unnecessarily complicated. A full repopulate each time will be easier and won't differ much in terms of computational expense.
This behavior is built in to BindingSources using DataSets in .Net 2.0.
For .Net 3.0+, you can use LINQ.