[ACCEPTED]-How do you bind a CollectionContainer to a collection in a view model?-data-binding

Accepted answer
Score: 72

The CompositeCollection has no DataContext, the bindings in the CollectionContainers will 11 not work if they bind directly to a property 10 (which implicitly uses the DataContext as source).

You 9 need to explicitly specify a source, i would 8 suggest you name the control with your DataContext and 7 use x:Reference to get it (ElementName will not work) or you use 6 a StaticResource, e.g.

<CollectionContainer Collection="{Binding DataContext.GreekGods, Source={x:Reference myStackPanel}}"/>
<CollectionContainer Collection="{Binding GreekGods, Source={StaticResource CompositeCollectionVM}}"/>

Note that when using x:Reference the compiler 5 easily trips you up with cyclical dependency 4 errors, to avoid those place your CompositeCollection in the 3 resources of the control you reference, then 2 insert it wherever it belongs using the 1 StaticResource markup extension.

Score: 5

An IMultiValueConverter is a nice fit for CompositeCollection but not for your 1 specific case where you add stuff in xaml.

Converter:

using System;
using System.Collections;
using System.Globalization;
using System.Windows.Data;

public class CompositeCollectionConverter : IMultiValueConverter
{
    public static readonly CompositeCollectionConverter Default = new CompositeCollectionConverter();

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var compositeCollection = new CompositeCollection();
        foreach (var value in values)
        {
            var enumerable = value as IEnumerable;
            if (enumerable != null)
            {
                compositeCollection.Add(new CollectionContainer { Collection = enumerable });
            }
            else
            {
                compositeCollection.Add(value);
            }
        }

        return compositeCollection;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException("CompositeCollectionConverter ony supports oneway bindings");
    }
}

Usage:

<ListBox>
    <ListBox.ItemsSource>
        <MultiBinding Converter="{x:Static local:CompositeCollectionConverter.Default}">
            <Binding Path="Col1" />
            <Binding Path="Col2" />
            ...
        </MultiBinding>
    </ListBox.ItemsSource>
    ...
</ListBox>

More Related questions