Как определить, изменился ли элемент в моем ObservableCollection - программирование
Подтвердить что ты не робот

Как определить, изменился ли элемент в моем ObservableCollection

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

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

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

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

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

4b9b3361

Ответ 1

  • Внесите 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 свой viewmodel, например, вы можете привязать свойство Button.IsEnabled непосредственно к нему.

Ответ 2

Просто используйте 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.
}

Ответ 3

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

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

Ответ 4

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

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

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