Событие CollectionChanged не регистрируется при использовании конвертера? - PullRequest
2 голосов
/ 18 марта 2011

У меня есть ObservableCollection с именем Collection1, который я хочу связать с ItemsSource ListBox через конвертер.

Когда я указываю конвертер, привязка не работает - он использует конвертер только для инициализации и никогда больше.

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

Я узнал, что CollectionChanged Обработчик события не был установлен, когда был указан конвертер, но был установлен, когда конвертер не был указан.Я не знаю, почему это так.

Подводя итог:

Это делает не работа:

<ListBox Name="theListBox" 
         Margin="8,28,8,8"
         ItemsSource="{Binding Collection1, Converter={StaticResource myConverter}}"
         ItemContainerStyle="{DynamicResource ContainerStyle}" /> 

Collection1.CollectionChanged is null.

Это делает работа:

<ListBox Name="theListBox" 
         Margin="8,28,8,8"
         ItemsSource="{Binding Collection1}"
         ItemContainerStyle="{DynamicResource ContainerStyle}" /> 

Collection1.CollectionChanged is not null.

Если кто-нибудь может помочь, я буду признателен.Спасибо!


Вот мое решение этой проблемы, основанное на других комментариях ниже.

Вместо привязки через конвертер, я создал свойство ObservableCollection в классе для привязки изатем вручную подписался на событие Collection1.CollectionChanged в коде.

public partial class MyScreen : UserControl
{
    public ObservableCollection<Class2> BindingCollection { get; set; }  // <-- Bind to this

    public MyScreen()
    {
        this.InitializeComponent();

        BindingCollection = new ObservableCollection<Class2>();

        Collection1.CollectionChanged += new NotifyCollectionChangedEventHandler(Collection1_CollectionChanged);
        MediViewData.Instance.ActivePatientCareReport.PropertyChanged += new PropertyChangedEventHandler(ActivePatientCareReport_PropertyChanged);

    }

    void Collection1_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        BindingCollection.Clear();

        foreach (var c1 in Collection1)
        {
            var c2 = ConvertClass1ToClass2(c1);
            if (c2 != null) BindingCollection.Add(c2);
        }
    }
}

XAML выглядит примерно так:

<ListBox x:Name="MyListBox" 
         Margin="8,28,8,8"
         ItemContainerStyle="{DynamicResource ContainerStyle}" 
         ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=BindingCollection}" />

Кажется, что он работает просто отлично.

1 Ответ

2 голосов
/ 18 марта 2011

ItemsControl.ItemsSource имеет логику для подключения к событию CollectionChanged и соответственно обновляет свою коллекцию Items. Если вы не возвращаете тот же экземпляр ObservableCollection из конвертера, уведомления CollectionChanged не могут автоматически распространяться из Binding через конвертер.

Точное исправление будет зависеть от того, что происходит в конвертере.

UPDATE

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

...