Как определить, изменился ли элемент в моей коллекции ObservableCollection - PullRequest
20 голосов
/ 24 января 2012

У меня есть сетка данных, связанная с ObservableCollection<Product>. Когда сетка обновляется, это автоматически обновляет объект Product в моей коллекции.

То, что я хочу сделать сейчас, - это иметь какую-то четность, которая срабатывает при обновлении любого объекта в коллекции, или какая-то привязка к коллекции, которая будет возвращать true / false депедант, если какой-либо Продукт был обновлен.

Общая цель состоит в том, чтобы кнопка «Сохранить» в моем главном окне была отключена, если в мою коллекцию не было внесено никаких изменений, и включена, если изменения были внесены.

Я прочитал INotifyPropertyChange, но я не понимаю, как я могу использовать это для мониторинга изменений всей коллекции.

Кроме того, если я реализую этот интерфейс в своем классе Product, я не вижу, как мой пользовательский интерфейс может отслеживать каждый продукт в коллекции - или это возможно?

Ответы [ 4 ]

15 голосов
/ 24 января 2012
  • Реализация INotifyPropertyChanged в вашем классе Product с уведомлением для каждого свойства.
  • Реализация INotifyPropertyChanged в вашей модели представления.
  • Добавление свойства IsDirty в вашу ViewModel(с уведомлением через INotifyPropertyChanged.
  • В вашей модели представления подпишитесь на CollectionChanged

    public YourViewModel()
    {
        ...
        YourCollection.CollectionChanged += YourCollection_CollectionChanged; 
        ...
    }
    
    private void YourCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args)
    {
        if (args.OldItems != null)
            foreach(var oldItem in args.OldItems)
                oldItem.PropertyChanged -= YourItem_PropertyChanged;
    
        if (args.NewItems != null)
            foreach(var newItem in args.NewItems)
                newItem.PropertyChanged += YourItem_PropertyChanged;
    }
    
    private void Youritem_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs args)
    {
        IsDirty = true;
    }
    
  • Теперь вы можете привязать к IsDirty свойствуНапример, вы можете привязать свойство Button.IsEnabled непосредственно к нему.

2 голосов
/ 24 января 2012

Просто используйте ObservableCollection. У него есть событие под названием CollectionChanged . Если вы зарегистрируете его, вы можете делать то, что вы хотите. Пример:

ObservableCollection<string> strings = new ObservableCollection<string>();
strings.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(changed);
strings.Add("Hello");
strings[0] = "HelloHello";

И

private void changed(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args)
{
    //You get notified here two times.
}
1 голос
/ 24 января 2012

Логика должна идти в вашей модели (класс продукта).Чистым подходом было бы предоставить в вашей модели IsDirty свойство (поддерживаемое полем).

И ваша ViewModel будет иметь привязку Command с CanSave, проверяющей внутреннюю коллекцию, и возвращать true, если Any изпредмет в коллекции IsDirty=true.

0 голосов
/ 24 января 2012

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

Тем не менее, я думаю, вам не нужно делать все это, чтобы выяснить, изменилась ли ячейка в вашей сетке.Я думаю, что вы можете сделать что-то вроде того, что они делают здесь:

http://social.msdn.microsoft.com/Forums/en/wpf/thread/81131225-90fb-40f9-a311-066952c7bc43

...