My View (V) is bound to a ViewModel (VM). In the V I have a List of objects that is displayed in a ListView. In the ListView I use an ItemTemplate, each item is displayed as a Label holding the name of the item and a Combobox with the SelectedItem set to another property of the item. The Combobox is bound to a List which is also part of the VM of the main V (I bind it using ElementName=ListBox.DataContext in the Binding...)
So far everything works very well. The problem is that the Combobox can contain a lot of entries and I would like to use grouping or filtering. I know how to use filtering and grouping using ListCollectionView. But I cannot simply change my List to a ListCollectionView since it is used multiple times (for each item in the ListView). One ListCollectionView cannot be used multiple times but have different SelectedItem for each usage.
Now I am looking for an easy way to use grouping in the ListView's Combobox.
Is there a way to define the ListCollectionView directly in XAML inside the ItemTemplate (DataTemplate)? I also thought about using a (non-shared) Converter in the ItemsSource Binding that converts my List of objects into a ListCollectionView (if I use OneTime Binding, the Converter will only be called once, is that correct?)? I know I could also put each object in the List in the VM in its own ViewModel and each of it provides its own ListCollectionView for the Combobox, but that seems to be the most complicated solution (but maybe the cleanest?)
Any other suggestions or advice?
If you want to use the same ICollectionView in multiple comboboxes (or other selectors) without synchronizing their selected item, you need to explicitely set IsSynchronizedWithCurrentItem="False" on each combobox.
Related
I have a DataGrid I bound to an ObservableCollection. The grid is configured in a way that the user can add rows (this is the desired behavior). Elsewhere in my GUI, I bound the same collection to be the ItemsSource of a ComboBox. There, it shows the {NewItemPlaceholder} I don't want.
I found a similar question where it is suggested to set CanUserAddRows to false but then I would need a dedicated button or context menu item to add a new row which I find less intuitive.
So, is there a way to get rid of this placeholder by e.g. some means of filtering the ItemsSource?
Followup 1
I discovered the following strange behavior:
When I directly bind the ItemsSource of the combo box to the observable collection, I get the {NewItemPlaceholder}
When I declare a CollectionViewSource as a Resource of my combo box, set its Source to the observable collection and set in turn my CollectionViewSource as the ItemsSource of the combo box, the {NewItemPlaceholder} disappears. I don't even have to specify a filter.
How do I get the list of selected items from a ListCollectionView? I see CurrentItem returns for single selection but I don't see anything to return the list of selected items in multi-select mode.
ListCollectionView or other types implementing ICollectionView are wrapper over source collection which WPF creates internally to bind with instead of direct binding to source collection. So, it does not have any such property to get selected items on GUI which is more or less a UI thing.
You need to get the SelectedItems from an UI component. ListCollectionView must be binded to ListBox. Access ListBox SelectedItems property to get selected items on view.
In my wpf project I'm using a datatemplate (which consists of a textblock) as an itemtemplate to my listbox. The itemsource is a List of which there are 6 items. How can I loop through the 6 textblock's that are created at runtime?
Thanks
Do not do it.
Bind everything you need to change to your items and then just change the bound properties, messing with template controls is never a good idea, especially with virtualizing items controls where they may not even exist for all items.
(What you should not use: ItemsControl.ItemContainerGenerator.ContainerFromItem)
how can i bind SelectedItems of a ListView?
My ListView has multipleSelection attribute and I'm using CollectionView for its contents..
I've heard about Attached property and I tried implementing this with the one I found here:
Sync SelectedItems in a muliselect listbox with a collection in ViewModel
I can multiple select the items by clicking rows but I can't use the Shift keyboard for multi-selecting many rows instantly... Also, when I filter my collection and refresh it, my selection are all deselected after the refresh..
How can I make it so that whenever my CollectionView refreshes, the previously selecteditems are still selected after the refresh...?
Can someone also help me how to manipulate logically the selected items through my viewmodel?
May be you should add the IsSelected property to the ListViewItem's view model.
You will have to use your own code to keep the selected items after a refresh. Maybe make a copy of your collection before the refresh and afterwards a simple for to check all the checked items in your current collection.
Change your selectection mode to extended for your listbox for the shift key to work.
As for manipulating logically the selected items, you will have to give a lot more info on what exactly you want done.
I'm using an observable collection to hold all files dragged into a ListBox control and binding the collection to the itemssource, now I am using an extended selection mode so I can select more than one item in the ListBox, my problem is if I have selected index 0, 4 and 7 as an example, how could I bring these values up into an array?
As there is no way to bind to the SelectedItems property of the ListBox control, you will need to watch for this in the back-end (either ViewModel or code-behind).
Depending on when you want this to happen would depend on your approach.
If you want the indexes to be updated OnSelectionChanged you will need to hook that event either using an event handler, or using the AttachedCommandBehaviour approach.
To get the indexes (collection index, not necessarily display index) you will then loop through the SelectedItems collection and get the IndexOf value from the ItemsSource collection (in your case the ObservableCollection).
If your list has been sorted after setting the ItemsSource you may need to take a different approach, however.