Search code examples
wpfbindingitemscontrolmultibinding

How to switch between 2 data sources for ListBox.ItemsSource


What is the best/elegant way to bind ItemsControl.ItemsSource to 2 different sources best on a given property?

The binding should be done only to one of the 2 collection, the selection to which collection the ItemsControl is bound to should be based on some property.

I have a View which is bound to a ViewModel. The collections which I want to bind to are located in different hierarchy path under that ViewModel.

I've a solution which is based on MultiBinding but I think there should be more elegant solution.

<CollectionViewSource x:Key="CVS">
      <CollectionViewSource.Source  >
          <MultiBinding Converter="{StaticResource myMultiBindingConverter}">
              <Binding  Path="XXXX.YYYY.ObservableCollection1"  />
              <Binding Path="XXXX.ObservableCollection2" />                    
          </MultiBinding>
      </CollectionViewSource.Source>                            
</CollectionViewSource>

<ListBox  x:Name="myListBox"                                   
          ItemsSource="{Binding Source={StaticResource CVS}}" />

the Converter:

public class myMultiBindingConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {

        foreach (var item in values)
        {
            if(myDependecyProperty == getFirstCollection)
            {
              //make sure the item is of first collection type based on its item property
              return item;
             }
            else
            {
              //make sure the item is of the second collection type
              return item;
            }

        }
        return null;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter,
        System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Solution

  • A DataTrigger would probably be more appropriate here since you want to change the ItemsSource binding based on another value

    <Style x:Key="MyListBoxStyle" TargetType="ListBox">
        <Setter Property="ItemsSource" Value="{Binding XXX.ObservableCollection2}" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding SomeValue}" Value="SecondCollection">
                <Setter Property="ItemsSource" Value="{Binding XXX.YYY.ObservableCollection2}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
    

    Unlike a Converter, a DataTrigger will correctly get re-evaluated whenever the triggered value changes