У меня xaml вот так:
<controls:RadComboBoxEx ItemsSource="{Binding Projects}"
SelectedItem="{Binding SelectedProject}"
DisplayMemberPath="Title"/>
<TextBox Text="{Binding SelectedProject.Title}" />
RadComboBoxEx - это локальный класс, который расширяет RadComboBox от Telerik и отменяет значение по умолчанию свойства со значениями по умолчанию для всей компании:
this.IsEditable = true;
this.IsReadOnly = false;
this.OpenDropDownOnFocus = true;
this.CanAutocompleteSelectItems = false;
this.StaysOpenOnEdit = true;
this.IsFilteringEnabled = true;
this.TextSearchMode = TextSearchMode.Contains;
... и выполняет дополнительную обработку событий.
Когда мое приложение запускается и заполняются проекты, это работает как шарм. Пользователь может начать вводить текст в поле, увидеть, что он набирает, и получить отфильтрованный список элементов для выбора. Они выбирают элемент, и отображается полный заголовок, даже если они набрали только часть заголовка.
Теперь ... пользователь выбирает "Обновить" (элемент пользовательского интерфейса и метод не показаны). Фоновый код переходит в базу данных и подбирает новое название проекта. Он сохраняет тот же объект, просто обновляет свойства объекта, которые изменились. Срабатывают события PropertyChanged
, TextBox
отображает обновления, элементы в раскрывающемся списке со списком отображают обновления, но выбранный текст элемента не обновляется.
Сначала я попытался добавить свойство Text
и привязать его к SelectedProject.Title
. Двусторонняя привязка позволяла обновлять текст, но вызывала всевозможные проблемы, поскольку значения объектов изменялись непреднамеренно. Можно было бы ожидать, что OneWay
привязка будет работать, но никаких обновлений из DataContext не потребовалось, за исключением UpdateSourceTrigger=LostFocus
, чего на самом деле недостаточно.
Затем я обнаружил, что если я установлю IsEditable="False"
, отображение выбранного элемента будет обновляться без привязки к свойству Text. Но тогда пользователь не мог видеть, что он набирает, при попытке отфильтровать список. Я подумал об изменении TextSearchMode.Contains
на TextSearchMode.StartsWith
, но это подойдет только для некоторых комбинированных полей.
Я попытался принудительно привязать SelectedItem
к TwoWay
и вызвать событие PropertyChanged
, сообщающее, что SelectedProject
изменилось, даже если оно не изменилось, и не было изменений в поведении.
Очевидно, что TextBox, который отображается, когда IsEditable
имеет значение true, не привязан (по умолчанию, если вы тупо не привязываете два способа к свойству Text
^) непосредственно к выбранному элементу, поскольку вы хотите, чтобы пользователь, вводящий текст, подключался к фильтру, а не к выбранному элементу . Однако при выборе элемента кажется, что он правильно заполняет всю строку, поэтому должен быть какой-то способ вызвать событие при изменении выбора. (Несмотря на мою предыдущую неудачную попытку форсировать это с помощью события PropertyChanged
, это должно быть так.)
Поэтому я перебрал его в своем методе обновления.
Project temp = this.SelectedProject;
this.SelectedProject = null;
this.SelectedProject = temp;
Это сработало! Итак, где-то в цепочке событий внутри элемента управления не было никаких изменений - ›в цепочке не было прерывания действия, и он никогда не смотрел на изменение вложенных свойств для обновления свойства Text.
Итак, у меня есть хак, который работает в этом конкретном случае, но я должен сделать это в нескольких местах, и я бы не хотел оставлять эту ловушку для следующего разработчика в нашей команде. Могу ли я что-нибудь сделать в нашем RadComboBoxEx, чтобы получить правильный поток событий для этого типа изменений?
UpdateSourceTrigger
какPropertyChanged
иMode
вTwoWay
в привязке. - person Rufw91   schedule 06.08.2020