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.
Related
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.
In the following link, the author shows how to create a binding source and add sorting function to a grid view. It should work similarly for combobox datasource. However does it have any benefit to do it for simpler controls like combobox or listbox? I can just assign a list of type List<AClass> and then assign the DisplayMember and Value for the controls.
http://aviadezra.blogspot.com/2008/06/binding-domain-objects-in-visual-studio.html
Even for data grid view, does it work well for complex situation like, for example, sorting on a grid view with paging? Looks the class PropertyComparerCollection in the example only works the loaded data.
The article is focused on binding complex business objects to the grid view. This has been a intensively debated subject since .Net Framework 2.0. If the properties of your bound type are no longer primitive, then you have to get your hands dirty to support sorting, filtering or searching.
There are plenty generic classes for this goal, but I would recommend this implementation, with a nice video demo here.
However, if you're not aiming at a data grid view, but rather at a combo box or list box, and wish not to modify the underlying store while sorting or filtering, you could still use a custom class derived from IBindingListView and BindingList(of T), like the one suggested above and manually call ApplySort or ApplyFilter. The implementation in the article linked in your post and the one I suggested use temporary copies of the original data source for sorting/filtering.
Furthermore, for paging instead of taking slices out of the original data source, you'd be taking slices out of the wrapped sortable view of that data source.
With a list view containing items I can reorder which gives a nice UI effect.
I have my item source for the list view hooked up to an observable collection. Is there anyway with the framework I could programatically simulate a reorder and give the same effect you would have if you actually reordering?
The only way I've been able to slightly achieve this is to literally clear all the items from my data source then repopulate after shuffling the items, however it doesn't look nice.
Well, you could sort the items in code-behind in a temporary helper array and then according to the order they are in in the sorted one start periodically moving items one-by-one in a small time interval (with DispatcherTimer) withing the collection - remove at it's index and insert somewhere it belongs. I think there is no built-in way to do it in a simpler manner.
I'm working with ListCollectionView objects to display lists of items. Currently, I'm building a screen that has two of these lists - one, completeList, holds all available items, the other one, sortedList, holds a subset of them with the item order being relevant. Possible actions here are
add or remove any of completeList's items to/from sortedList
move items up or down in sortedList
save the content of sortedList.
Now, my question is this: is there any possibility to insert items into sortedList at a defined position?
Right now, they will always be added at the end of the list, regardless of the currently marked item, and I didn't find a way around it - apart from the obvious dirty hack, which would have me store all items after the desired position, remove them from the list, add the new item, then re-add all stored items in the correct order.
Does ListCollectionView offer any such functionality, or is there another CollectionView class that would do the trick?
You're actually asking for something that's a logical contradiction. Suppose I have a ListCollectionViewsorted alphabetically:
American
Continental
Festival
Imperial
Tower
Worldwide
Should I be able to insert Luxor between American and Continental? Not if the view is sorted. There's only one place that item can go. And where it appears in the view is independent of where it might appear in the underlying list.
Without knowing more about your application, it's hard to know exactly what to suggest. But if a collection view is sorted, the way to make an item appear at a specific place in the view is to assign its sort key(s) a value that will, once the view is refreshed, cause it to appear in the desired location.
A fairly trivial (and generic) way of doing this is to add a DateTime property to the data item class, set it to DateTime.Now in the item's constructor, and make it the last sort key that the view uses. Then, when adding a new item, set its other sort key properties to the value of the currently selected item. If you do this, new items will always appear in the appropriate place, so long as you don't change the values of any of the sort key properties.
Having said that, from the other features you want to support, I believe that you shouldn't be using a ListCollectionView at all for what you're calling sortedList. This list isn't sorted. It's ordered, which is not at all the same thing. When the user moves an item up in the list, you actually want to change its position.
What you probably want to do is implement the list as an ObservableCollection, and wrap it in a view model class that exposes Items, SelectedItem, AddNewCommand, MoveUpCommand, MoveDownCommand, and SaveCommand properties. Then you can bind the ItemsSource and SelectedItem properties of a ListBox or ListView to Items and SelectedItem properties in the class, and bind buttons or hyperlinks or whatever in the UI to the commands. The commands will manipulate the Items property, using Remove and Insert, and since the Items is an ObservableCollection, the UI will stay in sync.
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.