Синхронизировать привязки нескольких свойств в UserControl - PullRequest
3 голосов
/ 11 июня 2010

У меня ужасное состояние гонки с пользовательским контролем WPF, который является своего рода расширенным ComboBox: UserControl в основном определяет два привязываемых свойства DependencyProperties, один - выбранный элемент, другой - список, из которого можно выбрать выбранный элемент.,Оба являются привязываемыми, поэтому элемент управления может быть инициализирован с выбранным элементом или без него, и оба свойства могут быть изменены посредством привязки (при изменении DataContext), в дальнейшем выбор может измениться из-за взаимодействия с пользователем.UserControl содержит ComboBox, чьи ItemsSource и SelectedItem синхронизированы с моим списком-свойством и SelectedItem из UserControl - пока что все хорошо.Проблема теперь в том, что если оба свойства изменяются (квази одновременно) извне при установке нового DataContext с обоими значениями, иногда случается, что SelectedItem установлен правильно, но обновление списка приводит к тому, что выбор сбрасывается до нуля, перезаписываяранее установленное значение -> повреждение моего DataContext.

Чтобы сделать его коротким: мне нужно найти способ "заблокировать" мой SelectedItem во время обновления списка - но просто наблюдать PropertyChanged-Events недостаточно, так как я получаюих ПОСЛЕ обновлений, где состояние для запоминания уже потеряно.Кроме того, я не могу определить, было ли изменение выбора вызвано пользователем или (правильно) привязкой или (не желательно) косвенно другой привязкой ... Я думаю, что мне понадобится какое-то событие BeforePropertyChanged или OnPropertyChanging для моих DependencyProperties - или другоеспособ упорядочения одновременных обновлений обоих свойств.

Любые предложения приветствуются:)

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

1 Ответ

1 голос
/ 19 марта 2012

Это может не помочь ситуации, и, вероятно, это неправильный способ сделать это, однако вы говорили о событии OnPropertyChanging для ваших свойств зависимостей.

Так получилось, что при создании свойств зависимостей вы можете указать обратный вызов в PropertyMetadata, который срабатывает при изменении свойства, которое имеет как старое, так и новое значения в EventArgument.

Вот пример свойства Text с обратным вызовом

public static DependencyProperty TextProperty = DependencyProperty.Register
                                                ("Text", typeof(string), 
                                                 typeof(DecimalTextBox), 
                                                 new PropertyMetadata("", OnTextPropertyChanged));

Последний параметр - это тот, который вы ищете.Первый параметр конструктора PropertyMetadata является значением по умолчанию для свойства.Во втором случае вы регистрируете обратный вызов с измененным свойством, который происходит при изменении свойства.

В этом обратном вызове вы можете обрабатывать привязки, чтобы убедиться, что вы не перезаписываете SelectedItem вашего datacontext.

Если честно, я не уверен, как это поможет вам в вашей ситуации, так как я все равно не знаю, как проверить, является ли значение NULL действительным или нет.(то, что я мог бы сделать, это не разрешать нулевые значения, если существует ItemSource, если только источник не изменяется [и я мог бы использовать какой-либо флаг в обратном вызове измененного ItemSource, который сбрасывается после изменения выбранного элемента]).Я не очень разбираюсь в асинхронности, но вы могли бы поставить здесь какую-то блокировку.

u_u

...