DataContext Refresh и PropertyChanging & amp; PropertyChanged События
-
03-07-2019 - |
Вопрос
Я нахожусь в ситуации, когда мне сообщают из внешнего источника, что конкретная сущность была изменена вне моего текущего контекста данных. Я могу найти сущность и вызвать обновление, например, так
MyDataContext.Refresh (RefreshMode.OverwriteCurrentValues, myEntity);
и свойства, которые были изменены на объекте, обновляются правильно. Однако ни один из INotifyPropertyChanging INotifyPropertyChanged, по-видимому, не возникает, когда происходит обновление, и это оставляет мой интерфейс, отображающий неверную информацию.
Мне известно, что Refresh () не может использовать правильные методы получения и установки свойства для объекта, чтобы вызвать события уведомления об изменении, но, возможно, есть другой способ сделать то же самое?
Я что-то не так делаю? Есть ли лучший метод, чем Refresh? Если Refresh - единственный вариант, у кого-нибудь есть обходной путь?
Решение
У меня была похожая проблема. Я связывался с TreeView и должен был вызвать Refresh в ответ на отмену пользователем операции редактирования. Метод Refresh ()
послушно возвращает все исходные значения обратно, но это не было отражено в моем TreeView UI. Посоветовавшись со всемогущим Google, я наткнулся на это решение:
CollectionViewSource.GetDefaultView(treeViewClusters.ItemsSource).Refresh();
Похоже, это заставляет мой TreeView обновлять все. Единственный недостаток (и он довольно серьезный) заключается в том, что он, кажется, разрушает все узлы дерева, что приводит к тому, что пользователь теряет свое место. С тем же успехом я мог бы установить для моего ItemsSource
значение null и обратно ... тот же эффект, хотя этот метод был бы проще, если бы у вас было несколько связанных текстовых полей или что-то еще, поскольку вам не нужно было бы перепривязать каждый.
Есть ли лучшее решение, чем это?
Редакция: Да, есть ...
Мой умный коллега придумал это решение, которое, похоже, помогает. В свой частичный класс для объекта Linq2Sql добавьте следующий код:
public void SendPropertiesChanged()
{
foreach (System.Reflection.PropertyInfo prop in this.GetType().GetProperties())
SendPropertyChanged(prop.Name);
}
Вы можете просто вызвать это в коде вашего приложения:
context.Refresh(RefreshMode.OverwriteCurrentValues, employee);
employee.SendPropertiesChanged();
Все элементы пользовательского интерфейса получают сообщение и обновляются соответствующим образом. Это работает даже для элементов управления в виде дерева и тому подобного, когда вы не хотите, чтобы пользовательский интерфейс отображался как «сброс». когда вы обновляете привязки.
Другие советы
Если вы знаете, что вызываете Refresh (), почему бы просто не обновить и все равно обновить интерфейс в этот момент?
PropertyChanging и PropertyChanged вызываются путем вызова установщика в классе сущностей, сгенерированном DBQ LINQtoSQL. Вызов Refresh () этого не делает:
[Column(Storage="_DisplayName", DbType="VarChar(50) NOT NULL", CanBeNull=false)]
public string DisplayName
{
get
{
return this._DisplayName;
}
set
{
if ((this._DisplayName != value))
{
this.OnDisplayNameChanging(value);
this.SendPropertyChanging();
this._DisplayName = value;
this.SendPropertyChanged("DisplayName");
this.OnDisplayNameChanged();
}
}
}