c# - ObservableCollection<T> 未收到有关 <T> 属性更改的通知

标签 c# wpf events mvvm

我有一个 Component 的 ObservableCollection,一个包含另一个 ObservableCollection 的类,一个 String 和一个 ComponentVersion。 SelectedComponentVersion 正在通过我的 View 正确更新,但我无法获取组件的属性来触发它的 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();
  }
}

然后我从 ListView 绑定(bind)到 Component 内的 SelectedComponent 属性。

我已经阅读了无数关于设置 CollectionChanged 的​​堆栈溢出,并尝试过实现它,但没有成功。

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

但在使用断点测试时,这永远不会命中。

我是不是完全错过了什么,失去了理智或愚蠢!有人请给我指出正确的方向,如果其中有任何意义的话。

P.S 我想到的另一个解决方案是在 ListView 中放置一个不可见的按钮,并让它发送一条命令来告诉虚拟机所选项目已更新。

最佳答案

在这种情况下,当集合中某个项目的属性发生变化时,我想做一些事情,我通常会在 中连接一个 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 属性更改时,您将使用此事件运行代码

关于c# - ObservableCollection<T> 未收到有关 <T> 属性更改的通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52973717/

相关文章:

javascript - 为什么 `event.preventDefault()` 不适用于两个嵌套的 div?

node.js - 捕捉 Ctrl-C 在 Node 中如何工作?

c# - 将枚举转换为整数

c# - 如何存储/检索大量用户身份声明

c# - 有没有办法将 C# 泛型字典拆分成多个字典?

wpf - XAML - 文本框换行

c# - 在不同窗口中单击按钮时调用函数(WPF 应用程序)

C# 从构造函数中调用事件

c# - 如何从另一个应用程序打开 WPF 窗口

wpf - WPF 的 IsDirty 实现