单例 OnPropertyChanged 未触发
Singleton OnPropertyChanged Not Firing
我有一个名为 DataModel 的 class,我在其中存储了 ObservableCollection
个项目。我使用的是静态 ObservableCollection
,但由于我想绑定到它,而 OnPropertyChanged 似乎不能正确地用于静态属性,我将其创建为单例:
public sealed class DataModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private static readonly DataModel instance = new DataModel();
private DataModel() { }
public static DataModel Instance
{
get
{
return instance;
}
}
#region Projects
private ObservableCollection<Project> projects = new ObservableCollection<Project>();
public ObservableCollection<Project> Projects
{
get
{
return projects;
}
set
{
if (projects == value)
{
return;
}
projects = value;
OnPropertyChanged("Projects");
}
}
#endregion Projects
public void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
然后当我点击一个按钮时,
Project newProject = new Project() { Title = "Test" };
DataModel.Instance.Projects.Add(newProject);
根据我从各种来源得出的结论,这应该可以正常工作。但是,永远不会调用 OnPropertyChanged
事件。如果我这样做
DataModel.Instance.Projects = new ObservableCollection<Project>();
它被调用了。但是添加一个项目到集合中不会调用它。
我希望它不起作用。因为您要将项目添加到 Observation 集合,在这种情况下,没有理由调用 setter,因此 OnPropertyChanged。这就是当您从调用代码初始化 DataModel.Instance.Projects 时它起作用的原因。您可以调用 属性 明确更改如下:
Project newProject = new Project() { Title = "Test" };
DataModel.Instance.Projects.Add(newProject);
DataModel.Instance.OnPropertyChanged("Projects");
免责声明:虽然这是可能的,但您确实不需要这样做。这就是为什么他们为我们提供了 ObservableCollection。任何 item/s 添加或删除 to/from 此类集合都会自动通知视图。如果这不是真的,为什么有人会使用 ObservableCollection 而不是简单的 List 进行数据绑定。
OnPropertyChanged
仅在重新分配 属性 时自动触发。这就是为什么重新分配整个集合会导致它被解雇的原因。修改集合会触发集合自己的 CollectionChanged
事件,因为您实际上并没有更改 Projects
引用,只是改变它所引用的同一个集合。
如果您的集合正确绑定到控件的 ItemsSource
属性,例如
<ListView ItemsSource="{Binding Projects}"/>
数据上下文是您的 DataModel
实例,除了添加新项目外,您不需要做任何事情。
如果您需要在集合更改时执行某些操作,请改为订阅其 CollectionChanged
事件:
private DataModel()
{
Projects.CollectionChanged += Projects_CollectionChanged;
}
private void Projects_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
// An item was added...
}
}
我有一个名为 DataModel 的 class,我在其中存储了 ObservableCollection
个项目。我使用的是静态 ObservableCollection
,但由于我想绑定到它,而 OnPropertyChanged 似乎不能正确地用于静态属性,我将其创建为单例:
public sealed class DataModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private static readonly DataModel instance = new DataModel();
private DataModel() { }
public static DataModel Instance
{
get
{
return instance;
}
}
#region Projects
private ObservableCollection<Project> projects = new ObservableCollection<Project>();
public ObservableCollection<Project> Projects
{
get
{
return projects;
}
set
{
if (projects == value)
{
return;
}
projects = value;
OnPropertyChanged("Projects");
}
}
#endregion Projects
public void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
然后当我点击一个按钮时,
Project newProject = new Project() { Title = "Test" };
DataModel.Instance.Projects.Add(newProject);
根据我从各种来源得出的结论,这应该可以正常工作。但是,永远不会调用 OnPropertyChanged
事件。如果我这样做
DataModel.Instance.Projects = new ObservableCollection<Project>();
它被调用了。但是添加一个项目到集合中不会调用它。
我希望它不起作用。因为您要将项目添加到 Observation 集合,在这种情况下,没有理由调用 setter,因此 OnPropertyChanged。这就是当您从调用代码初始化 DataModel.Instance.Projects 时它起作用的原因。您可以调用 属性 明确更改如下:
Project newProject = new Project() { Title = "Test" };
DataModel.Instance.Projects.Add(newProject);
DataModel.Instance.OnPropertyChanged("Projects");
免责声明:虽然这是可能的,但您确实不需要这样做。这就是为什么他们为我们提供了 ObservableCollection。任何 item/s 添加或删除 to/from 此类集合都会自动通知视图。如果这不是真的,为什么有人会使用 ObservableCollection 而不是简单的 List 进行数据绑定。
OnPropertyChanged
仅在重新分配 属性 时自动触发。这就是为什么重新分配整个集合会导致它被解雇的原因。修改集合会触发集合自己的 CollectionChanged
事件,因为您实际上并没有更改 Projects
引用,只是改变它所引用的同一个集合。
如果您的集合正确绑定到控件的 ItemsSource
属性,例如
<ListView ItemsSource="{Binding Projects}"/>
数据上下文是您的 DataModel
实例,除了添加新项目外,您不需要做任何事情。
如果您需要在集合更改时执行某些操作,请改为订阅其 CollectionChanged
事件:
private DataModel()
{
Projects.CollectionChanged += Projects_CollectionChanged;
}
private void Projects_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
// An item was added...
}
}