Singleton OnPropertyChanged不发射

时间:2015-10-06 04:43:52

标签: c# inotifypropertychanged uwp

我有一个名为DataModel的类,我正在存储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>();

它被称为。但是将一个项目添加到该集合中并不会调用它。

2 个答案:

答案 0 :(得分:2)

OnPropertyChanged仅在重新分配该属性时自动触发。这就是为什么重新分配整个集合会导致它被解雇的原因。修改集合会触发集合自己的CollectionChanged事件,因为您实际上并未更改Projects引用,只是改变了它所引用的相同集合。 / p>

如果您的收藏集正确绑定到控件的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...
    }
}

答案 1 :(得分:0)

我希望它不起作用。因为您要向Observation集合添加项目,在这种情况下,没有理由调用setter,因此 OnPropertyChanged 。这就是当你从调用代码初始化 DataModel.Instance.Projects 时它的工作原理。您可以显式更改属性,如下所示:

Project newProject = new Project() { Title = "Test" };
DataModel.Instance.Projects.Add(newProject);
DataModel.Instance.OnPropertyChanged("Projects");

免责声明:虽然这是可能的,但你真的不需要这样做。这就是为什么他们为我们提供了 ObservableCollection 。向此类集合添加或删除的任何项目将自动通知视图。如果不是这样,为什么有人会使用 ObservableCollection 而不是简单的 List 进行数据绑定。