Почему ObservableCollection не обновляется при изменении элементов? - PullRequest
7 голосов
/ 16 июля 2009

Я заметил, что ObservableCollection в WPF отражает изменения в графическом интерфейсе только путем добавления или удаления элемента в списке, но не путем его редактирования.

Это означает, что вместо этого я должен написать свой собственный класс MyObservableCollection. В чем причина такого поведения?

Спасибо

Ответы [ 5 ]

12 голосов
/ 16 июля 2009

ObservableCollection не имеет возможности узнать, вносите ли вы изменения в содержащиеся в нем объекты - если вы хотите получать уведомления, когда эти объекты изменяются, вы должны также сделать эти объекты наблюдаемыми (например, если эти объекты реализуют INotifyPropertyChanged)

1 голос
/ 31 августа 2011

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

1 голос
/ 08 апреля 2010

Другим способом достижения этой цели является реализация нового класса XXXViewModel, производного от DependencyObject, и помещения его в ObservableCollection.

для этого взгляда на это очень хорошее введение MVVM: http://blog.lab49.com/archives/2650

Примером такого класса будет:

public class EntryViewModel : DependencyObject
{
    private Entry _entry;
    public EntryViewModel(Entry e)
    {
        _entry = e;
        SetProperties(e);
    }

    private void SetProperties(Entry value)
    {

        this.Id = value.Id;
        this.Title = value.Title;
        this.CreationTimestamp = value.CreationTimestamp;
        this.LastUpdateTimestamp = value.LastUpdateTimestamp;
        this.Flag = value.Flag;
        this.Body = value.Body;
    }


    public Entry Entry
    {
        get {
            SyncBackProperties();
            return this._entry;
        }
    }


    public Int64 Id
    {
        get { return (Int64)GetValue(IdProperty); }
        set { SetValue(IdProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Id.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IdProperty =
        DependencyProperty.Register("Id", typeof(Int64), typeof(EntryViewModel), new UIPropertyMetadata(new Int64()));

}}

важные вещи здесь: - это происходит от DependencyObject - он работает с DependencyProperties для поддержки привязки данных WPF

ш sargola

0 голосов
/ 16 июля 2009

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

Вместо этого вы можете реализовать коллекцию с помощью метода обновления, который специально запускает событие ContentChanged (не уверен насчет имени). Это не красиво, но, по крайней мере, довольно легко иметь дело.

В идеале, как говорит kragen2uk, было бы лучше сделать объекты видимыми и сохранить код вашего клиента чистым и простым.

см. Также этот вопрос .

0 голосов
/ 16 июля 2009

Возможно, потому что элементы не имеют возможности оповещать коллекцию при редактировании - то есть они могут быть недоступны для наблюдения. Другие классы будут иметь похожее поведение - нет способа предупредить вас о каждом изменении в графе ссылочных классов.

...