Как использовать свойство модели представления в CompositeCollection?

Когда у меня есть поле со списком в моем представлении и я хочу, чтобы пустой элемент мог отменить выбор опции, я использую этот код в своем представлении:

<ComboBox.Resources>
    <CollectionViewSource x:Key="comboBoxSource" Source="{Binding ElementName=ucPrincipal, Path=DataContext.MyProperty}" />
</ComboBox.Resources>
<ComboBox.ItemsSource>
    <CompositeCollection>
        <entities:MyType ID="-1"/>
        <CollectionContainer Collection="{Binding Source={StaticResource comboBoxSource}}" />
    </CompositeCollection>
</ComboBox.ItemsSource>

В данном случае это представление, которое устанавливает идентификатор в -1, чтобы указать, что это особый элемент. Но мне не очень нравится это решение, потому что модель представления зависит от того, правильно ли оно установлено.

Так что я думаю иметь это свойство в моей модели представления:

public readonly MyType MyNullItem = new MyType();

Но я не знаю, как использовать его в моей составной коллекции в представлении вместо:

<entities:MyType ID="-1"/>

Является ли это возможным?

Благодарю.

1 ответ

Решение

Вам нужен какой-то конвертер связывания, который бы объединял один список и один объект в CompositeCollection, Некоторое время назад я реализовал похожий конвертер с той лишь разницей, что он конвертирует несколько коллекций в одну:

/// <summary>
/// Combines multiple collections into one CompositeCollection. This can be useful when binding to multiple item sources is needed.
/// </summary>
internal class MultiItemSourcesConverter : IMultiValueConverter {
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
        var result = new CompositeCollection();

        foreach (var collection in values.OfType<IEnumerable<dynamic>>()) {
            result.Add(new CollectionContainer { Collection = collection });
        }
        return result;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
        throw new NotSupportedException();
    }
}

И использование такого конвертера выглядит в XAML следующим образом:

<ComboBox.ItemsSource>
    <MultiBinding Converter="{StaticResource MultiItemSourcesConverter}">
        <Binding Path="FirstCollection" />
        <Binding Path="SecondCollection" />
    </MultiBinding>
</ComboBox.ItemsSource>
Другие вопросы по тегам