Вопрос

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

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();
        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top