ObservableCollection <T>не получает уведомления об изменении свойства <T> - PullRequest
0 голосов
/ 24 октября 2018

У меня есть ObservableCollection компонентов, класс с другой ObservableCollection, String и ComponentVersion.SelectedComponentVersion обновляется через мой вид правильно, но я не могу получить свойство Components для запуска его setter / OnPropertyChanged.

private ObservableCollection<Component> components
public ObservableCollection<Component> Components
{
   get { return foo; }
   set { foo = value; OnPropertyChanged(); }
}

Вот класс Component.

public class Component : ViewModelBase
{
  private string componentName;
  private ObservableCollection<ComponentVersion> componentVersions;
  private ComponentVersion selectedComponent;

  public string ComponentName
  {
     get { return componentName; }
     set { componentName = value; OnPropertyChanged(); }
  }
  public ObservableCollection<ComponentVersion> ComponentVersions
  {
     get { return componentVersions; }
     set { componentVersions = value; OnPropertyChanged(); }
  }
  public ComponentVersion SelectedComponent
  {
     get { return selectedComponent; }
     set { selectedComponent = value; OnPropertyChanged(); }
  }

  public Component(string componentName, List<ComponentVersion> componentVersion)
  {
     ComponentName = componentName;
     ComponentVersions = componentVersion.ToObservableCollection();
  }
}

Затем у меня есть привязка из списка к свойству SelectedComponent внутри компонента.

Я прочитал бесчисленные переполнения стека о настройке CollectionChanged и безуспешно пытался реализовать его.

Components.CollectionChanged += stuff;
private void stuff(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
   throw new System.NotImplementedException();
}

но это никогда не проверяется с помощью контрольных точек.

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

PS Еще одно решение, которое я думаю, заключалось бы в том, чтобы поместить невидимую кнопку внутри списка и заставить ее отправить командусообщить виртуальной машине, что выбранный элемент обновлен.

Ответы [ 4 ]

0 голосов
/ 24 октября 2018

В подобных случаях, когда я хочу что-то сделать, когда свойство элемента внутри коллекции изменяется , я обычно подключаю событие PropertyChanged к событию CollectionChanged

Вот пример кода:

public MyViewModel()
{
    // Setup Collection, with a CollectionChanged event
    Components = new ObservableCollection<Component>();
    Components.CollectionChanged += Components_CollectionChanged;

}

// In the CollectionChanged event (items getting added or removed from collection),
// hook up the PropertyChanged event
void Components_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.NewItems != null)
        foreach(MyType item in e.NewItems)
            item.PropertyChanged += Component_PropertyChanged;

    if (e.OldItems != null)
        foreach(MyType item in e.OldItems)
            item.PropertyChanged -= Component_PropertyChanged;
}

// In the PropertyChanged event, run some code if SelectedComponent property changed
void Component_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "SelectedComponent")
        DoWork();
} 

Обратите внимание, что здесь мы используем два отдельных события.

  • CollectionChanged событие запускается, когда изменяется сама коллекция.Это означает, что он настроен на новую коллекцию, или элементы добавлены или удалены из коллекции.

    Это захватывает вновь добавленные элементы и подключает обработчик PropertyChanged или отсоединяет обработчик PropertyChanged для элементов, удаляемых из коллекции.

  • PropertyChanged Событие запускается при изменении свойства изапускает событие.Это событие будет использоваться для запуска кода, когда свойство SelectedComponent любого элемента в коллекции изменится
0 голосов
/ 24 октября 2018

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

Одна вещь, которую вы можете сделать, это расширить класс ObservableCollection и переопределить функциональность, чтобы при изменении коллекции элементдобавленные или удаленные, вы затем просматриваете элементы в коллекции и «подключаете» интересующие вас события. Следует отметить, что вам, возможно, придется пройтись по коллекции, удалить обработчики событий и «подключить»их снова, чтобы прекратить получать несколько обработчиков событий, установленных для элементов в списке.

0 голосов
/ 24 октября 2018

ObservableCollection<T> не отправляет уведомления об изменениях свойств элементов.Тем не менее, пространство имен System.ComponentModel содержит другую коллекцию, которая поддерживает это: вы можете использовать вместо него BindingList<T>, что также поддерживается WPF (элементы должны реализовывать INotifyPropertyChanged).

Обратите внимание, чтоBindingList<T> плохо масштабируется, и его производительность начинает падать, превышая сотни и тысячи элементов, поскольку он всегда последовательно ищет измененный элемент, чтобы вернуть индекс элемента в его событии ListChanged.

0 голосов
/ 24 октября 2018

Ну, components не изменился.Я не уверен, правильно ли вы настроили свой обработчик, но даже если вы это сделали, событие CollectionChanged вызывается только , если коллекция изменилась (элемент добавлен или удален).

Позволяетскажем, у вас есть коллекция автомобилей, и все они красные.

Вы выбираете одну машину и устанавливаете ее цвет на синий.

Коллекция не изменилась.Это все те же машины.Ни одна машина не пропала, ни одна машина не была добавлена.

Вы, вероятно, хотите присоединиться к обработчикам всех автомобилей вместо обработчиков коллекции.

Итак, подведем итог:

ObservableCollection не получает уведомления об изменении свойства

Это правда, и это по замыслу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...