Странное поведение для свойства ViewModel, RaisePropertyChanged не выполняется - PullRequest
1 голос
/ 03 февраля 2011

Я заметил странное поведение с RaisePropertyChanged при добавлении объектов в свойство ViewModel.

private List<string> _items;
public List<string> Items
{
    get 
    {
        if(_items == null){ _items = new List<string>(); } 
        return _itmes; 
    }
    set
    {
        _items = value;
        RaisePropertyChanged("Items");
    }
}

Когда я добавляю объекты в коллекцию через свойство

Items.Add("new string");

RaisePropertyChanged никогда не вызывается.

Каков наилучший способ заставить RaisePropertyChanged работать так, как мне бы хотелось?

Ответы [ 2 ]

5 голосов
/ 03 февраля 2011

Ваш установщик будет вызываться при изменении коллекции, а не при изменении содержимого коллекции. Что вам нужно, это коллекция, которая информирует вас об изменениях. Посмотрите на класс ObservableCollection<T>. Зарегистрируйтесь, чтобы получать CollectionChanged событие, чтобы быть в курсе изменений.

Собственность с сеттером
В следующем примере показано, как вы можете работать с настраиваемым свойством, которое содержит наблюдаемую коллекцию. Сложность примера заключается в том, что коллекция может быть установлена ​​вне экземпляра. Если вам не нужна эта функция, решение станет намного проще.

private ObservableCollection<string> _items;
public ObservableCollection<string> Items {
    get {
        if (_items == null) { 
           // Create a new collection and subscribe to the event
           Items=new ObservableCollection<string>(); 
        }
        return _items;
    }
    set {
      if(value !=_items){
        if (null != _items) {
            // unsubscribe for the old collection
            _items.CollectionChanged -= new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_items_CollectionChanged);
        }
        _items = value;
        if (null != _items) {
            // subscribe for the new collection
            _items.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_items_CollectionChanged);    
        }
        // Here you will be informed, when the collection itselfs has been changed
        RaisePropertyChanged("Items");
    }
  }
}

void _items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
    // Here you will be informed, if the content of the collection has been changed.  
} 

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

private ObservableCollection<string> _items; 
public ObservableCollection<string> Items {
    get {
        if (_items == null) { 
           // Create a new collection and subscribe to the event
           _items=new ObservableCollection<string>(); 
           _items.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler
        }
        return _items;
    }
}

void _items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
    // Here you will be informed, if the content of the collection has been changed.  
} 

Дополнительная информация
Посмотрите на INotifyCollectionChanged для получения дополнительной информации об изменениях коллекции. Приведенные выше примеры вы также можете использовать более общие с IEnumerable<string> и INotifyCollectionChanged.

2 голосов
/ 03 февраля 2011

Конечно, он никогда не вызывается, потому что вы фактически не устанавливаете свойство (не вызывается установщик свойства Items), когда вы добавляете элемент в коллекцию.

В случае модификации коллекции вам нужно вызвать событие CollectionChanged. Для этого вам нужно использовать ObservableCollection<T> вместо обычного List<T>:

private ObservableCollection<string> _items;
public ObservableCollection<string> Items
{
    get 
    {
        if(_items == null){ _items = new ObservableCollection<string>(); } 
        return _itmes; 
    }
    set
    {
        _items = value;
        RaisePropertyChanged("Items");
    }
}

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

...