【问题标题】:Singleton OnPropertyChanged Not Firing单例 OnPropertyChanged 未触发
【发布时间】:2016-01-02 21:27:37
【问题描述】:

我有一个名为 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>();

它被调用。但是将项目添加到集合中不会调用它。

【问题讨论】:

    标签: c# inotifypropertychanged uwp


    【解决方案1】:

    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...
        }
    }
    

    【讨论】:

    • 啊哈!我在看完全错误的地方。我去忘记设置DataContext。 *捂脸*。只是假设它与 DataModel 有关,因为这是我第一次这样做——因此它在前 10 个小时内不起作用。但是,您的回答证实它确实是正确的,所以接受。
    • @Shawn:幸好我当时确定要考虑到这一点 :)
    【解决方案2】:

    我希望它不起作用。因为您正在将项目添加到观察集合,在这种情况下没有理由调用 setter 并因此 OnPropertyChanged。这就是当您从调用代码初始化 DataModel.Instance.Projects 时它起作用的原因。您可以如下调用明确更改的属性:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-28
      • 1970-01-01
      • 2019-05-26
      • 1970-01-01
      • 2021-12-11
      • 2021-02-13
      • 1970-01-01
      相关资源
      最近更新 更多