WPF, как связать две наблюдаемые коллекции разных, но связанных типов, используя конвертер значений? - PullRequest
2 голосов
/ 28 февраля 2011

У меня есть пользовательский элемент управления с наблюдаемой коллекцией (DP), содержащей объекты определенного типа. Я хочу связать его с другой наблюдаемой коллекцией, содержащей объекты другого типа в моей виртуальной машине. Как мне это сделать?

Должен ли я вообще что-то делать?

Edit. Конечно, привязка должна работать, когда элементы в коллекциях изменены с обеих сторон.

Ответы [ 3 ]

3 голосов
/ 28 февраля 2011
Комментарий

Meleak верен, вы должны как-то преобразовать одну коллекцию в другую и синхронизировать их. Вот как я это делал в прошлый раз:

Вид (я назвал его MyControl ниже) имеет свойство Items типа IEnumerable<Target>
DataContext имеет свойство Items типа IEnumerable<Source>

class CollectionsConverter : IValueConverter
{
    public object Convert(object value, ...)
    {
        var source = (ObservableCollection<Source>)value;
        var target = new ObservableCollection<Target>(source.Select(/* Convert items somehow /);
        // subscribe to both target's and source's 'CollectionChanged' events
        // and propagate them back and forth to another collection.
        // Propagated events should have converted items of course

        return target;
    }
    ...
}

Тогда в XAML:

<MyControl Items="{Binding Items, Converter=CollectionsConverter}" />

Что касается преобразования каждого элемента - это может быть либо общий код, который будет динамически определять способ преобразования Source в Target и наоборот, либо это должен быть код, который будет знать, какие именно типы он будет преобразовывать и как преобразовывать их.

0 голосов
/ 28 февраля 2011

ValueConverter не работает так, как вы описываете, вы должны создать новую коллекцию вручную.

Это не отвечает на ваш вопрос напрямую, но в ReactiveUI (http://www.reactiveui.net), этот сценарийэто довольно просто:

var derivedColl = someCollection.CreateDerivedCollection(x => new SomeOtherClass(x));
0 голосов
/ 28 февраля 2011

Используйте свой собственный класс конвертера, реализующий IValueConverter

<Code>

    public class ObserverTypeConverter:IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            //return your dependency type from here     
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            //return your view model type from here, this will get fired if your binding is two way
        }
    }

</Code>
...