【问题标题】:Throw CollectionChanged of ObservableCollection when nested Property changes嵌套属性更改时抛出 ObservableCollection 的 CollectionChanged
【发布时间】:2018-09-06 04:46:21
【问题描述】:

当嵌套元素发生变化并且我需要知道它时如何通知ObservableCollection<Book>

也许“ObservableCollection<Book>”和“Book”有一个成员“Chapter”。并且“章节”有一个名为“Name”的字符串属性,我更改了名称值。 当Name->Chapter -> Book -> ObservableCollection<Book> 中的属性“名称”更改时,如何抛出 ObservableCollection 的 CollectionChanged ?

MVVM 中的常用方法是通过 manuell 进行隧道传输,以便在触发 PropertyChange 时触发 CollectionChanged 吗??

谢谢:)


更新:我在这篇文章中找到了解决方案:ObservableCollection not noticing when Item in it changes (even with INotifyPropertyChanged)

-> 使用绑定列表或帖子中的某种 TrulyObservableCollection 因为 ObservableCollection 不会像我一样中继项目通知 已经提到了! difference between ObservableCollection and BindingList

-> 如果你使用 BindingList 记住这篇文章的缺点 http://www.themissingdocs.net/wordpress/?p=465


【问题讨论】:

    标签: c# mvvm nested observablecollection


    【解决方案1】:

    我过去也遇到过类似的问题。这是由于我使用了嵌套属性和缺少通知传播造成的。

    我通过在每次我的对象更改时订阅 PropertyChanged 事件来解决它。这样我可以在嵌套属性更新时更新我的​​集合。

    确保每个简单类型(例如您的 Name 属性)实现 OnPropertyChanged,然后每个复杂类型(例如您的 BookChapter 属性)实现通知传播。

    您的 Observable Collection 应相应更新。

    示例:

    private Book _book;
    
    public Book Book
        {
            get
            {
                return _book;
            }
            set
            {
                if (value == _book|| value == null)
                    return;
    
                if (_book!= null)
                    _book.PropertyChanged -= BookPropertyChanged;
    
                _book= value;
                _book.PropertyChanged += BookPropertyChanged;
    
                UpdateProperties();
            }
        }
    

    更新方法:

    private void BookPropertyChanged(object sender, PropertyChangedEventArgs args)
        {
            OnPropertyChanged(string.Empty);
        }
    
    public void UpdateProperties()
        {
            OnPropertyChanged(string.Empty);
        }
    
    public event PropertyChangedEventHandler PropertyChanged;
    
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    

    【讨论】:

    • 您好,感谢您的回答。我的问题不是没有抛出更改的属性。我的问题是,当集合中嵌套对象的 propertychanged 被抛出时,我想触发集合的 collectionchanged 事件。或者也许我只是原则上不明白一些东西:D
    • 我明白,但如果其中一个成员的属性更新,您的 ObservableCollection 将更新。例如,如果您的 Book 项目具有类型为 string 的 Name 属性并且您更改了它,那么您的 ObservableCollection 将更新。您面临的问题是因为在您的 Book 项目中更改复杂类型的属性不会为您的 Book 项目调用 OnPropertyChanged。此解决方案解决了该问题,从而解决了您面临的问题。
    • 根据我的经验,我有一个 Item1 类型的 ObservableCollection,其中包含 Item2 的属性,其中包含 Item3 的属性,然后包含简单类型,我会修改。这个解决方案对我有用。我能够修改层次结构中的任何属性,ObservableCollection 会更新。
    • 您需要嵌套属性的 Property Changed 事件来通知您的 Collection 以便它更新。这将允许您通过隧道发送通知。
    • 如果我更改集合中的名称属性,我的用户界面会更新。我认为是因为 WPF 使用反射来查找 INotifyPropertyChanged。但是集合本身并没有收到 INotifyPropertyChanged 的​​通知。但我会再次检查:/
    猜你喜欢
    • 2015-04-21
    • 1970-01-01
    • 2012-06-21
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 2013-01-12
    相关资源
    最近更新 更多