Multiple ComboBoxes Tied to a Shared Source for a Clear Choice

I am trying to link several ComboBox to a common collection of sources and ensure that after selecting a ComboBox this selected item is removed from another ComboBox. The collection is created dynamically, so I do it in code.

I have tried to implement this in several ways so far, and I just can't come up with something that really works.

I tried to use the default filter predicate, but it passes this element, and I don’t know which control the filter executes (and this does not even make sense conceptually).

I tried to create a new CollectionView, but the behavior ends up being different (receiving SelectionChange events, where there was no default view before).

I banged my head about this for several hours, and he simply does not want to work. I would appreciate if anyone is more experienced with WPF helping me with a working example. I would really like for him not to automatically select items from the collection and start empty (otherwise each ComboBox will have a great automatic selection, which is too exaggerated).

I'm really close to just offering a wide selection and checking it out later, but it seems like such a simple concept has such incredible difficulties.

thanks

+4
source share
2 answers

I'm not quite sure what I did wrong the first time, however I changed the situation a bit and got my initial attempt.

Perhaps the problems I ran into were the result of using CollectionView directly, which has a debug exit warning. It states that using CollectionView is not directly fully supported and may have incorrect behavior.

I ended up switching to ListCollectionView. I also created a new List <> containing the contents of my original collection, which allowed me to add an empty list to the list (without changing the original data structure). I simply ignore it when changing the selection and unconditionally include it in the Filter.

So, the steps to get it working:
1) ListCollectionView with IList source
2) Add a filter predicate to the view
3) Creating a binding with a view as a source
4) combo.SetBinding on ComboBox.ItemsSource
5) When choosing an event with a change, be sure to include each combined ItemsSource element in the ICollectionView and call Refresh (since it will need to be re-filtered, and notifications about changes in properties will not be noticed)

+1
source

Good question, I thought about this, and I will probably approach it with MultiBinding and the corresponding ValueConverter, i.e.

<StackPanel> <StackPanel.Resources> <local:ComboBoxItemsSourceFilter x:Key="ComboBoxItemsSourceFilter"/> </StackPanel.Resources> <ComboBox Name="cb1"> <ComboBox.ItemsSource> <MultiBinding Converter="{StaticResource ComboBoxItemsSourceFilter}"> <Binding Path="Emps"/> <!-- Source collection binding --> <Binding ElementName="cb2" Path="SelectedItem"/> <Binding ElementName="cb3" Path="SelectedItem"/> </MultiBinding> </ComboBox.ItemsSource> </ComboBox> <ComboBox Name="cb2"> <ComboBox.ItemsSource> <MultiBinding Converter="{StaticResource ComboBoxItemsSourceFilter}"> <Binding Path="Emps"/> <Binding ElementName="cb1" Path="SelectedItem"/> <Binding ElementName="cb3" Path="SelectedItem"/> </MultiBinding> </ComboBox.ItemsSource> </ComboBox> <ComboBox Name="cb3"> <ComboBox.ItemsSource> <MultiBinding Converter="{StaticResource ComboBoxItemsSourceFilter}"> <Binding Path="Emps"/> <Binding ElementName="cb1" Path="SelectedItem"/> <Binding ElementName="cb2" Path="SelectedItem"/> </MultiBinding> </ComboBox.ItemsSource> </ComboBox> </StackPanel> 
 public class ComboBoxItemsSourceFilter : IMultiValueConverter { #region IMultiValueConverter Members public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { var collection = new List<object>((object[])values[0]); foreach (var item in values.Skip(1)) { if (item != null) collection.Remove(item); } return collection; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotSupportedException(); } #endregion } 

Since you are doing this in code after adding all of these bindings, this should not be a big problem, just drag and drop all the lists into a list and you can iterate over them. The converter may need some tuning, since it is assumed that the input collection ( values[0] ) can be translated to object[] .

This way of doing this sadly raises many exceptions with a first chance, the reason of which I could not determine until now ...

The first random error like "System.Runtime.InteropServices.COMException" occurred in UIAutomationProvider.dll

+3
source

All Articles