INotifyPropertyChange ~ 当属性是集合并且新项目添加到集合中时,PropertyChanged 不会触发

发布于 2024-09-04 19:12:16 字数 659 浏览 4 评论 0原文

我有一个实现 INotifyPropertyChanged 接口的类。该类的一些属性是 List 类型。例如:

public List<string> Answers
{
    get { return _answers;  }
    set
    {
      _answers = value;
      onPropertyChanged("Answers")
    }
}

...

private void onPropertyChanged(string propertyName)
{
    if(this.PropertyChanged != null)
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

如果我分配一个新的 List回答,然后 PropertyChanged 事件按预期触发;但如果我使用 List Add 方法将字符串添加到答案列表中,则不会触发 PropertyChanged 事件。

我正在考虑向我的类添加一个 AddAnswer() 方法,该方法将处理调用列表的 Add 方法,并从那里调用 onPropertyChanged() ,但这是正确的方法吗?有更优雅的方法吗?

干杯, 康泰

I have a class that implements the INotifyPropertyChanged interface. Some of the properties of the class are of type List. For example:

public List<string> Answers
{
    get { return _answers;  }
    set
    {
      _answers = value;
      onPropertyChanged("Answers")
    }
}

...

private void onPropertyChanged(string propertyName)
{
    if(this.PropertyChanged != null)
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

If I assign a new List<string> to Answer, then the PropertyChanged event fires as expected; but if I add a string string to the Answer list using the List Add method, then PropertyChanged event doesn't fire.

I was considering adding an AddAnswer() method to my class, which would handle calling the lists's Add method and would call onPropertyChanged() from there, but is that the right way to do it? Is there a more elegant way of doing it?

Cheers,
KT

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

旧时模样 2024-09-11 19:12:16

您应该公开 ObservableCollection,它实现 INotifyCollectionChange 接口来引发其自己的更改事件。

您还应该删除属性设置器; 集合属性应为只读

当集合的内容发生更改时,您不应引发 PropertyChanged 事件。

You should expose an ObservableCollection<string>, which implements the INotifyCollectionChange interface to raise its own change events.

You should also remove the property setter; Collection properties should be read only.

You should not raise the PropertyChanged event when the contents of the collection change.

森林迷了鹿 2024-09-11 19:12:16

好吧,我终于遇到了这个问题,而且互联网上没有完整的答案,所以这里是没有人提到的缺失部分(也许是因为假设我们不是完全的白痴并且没有删除默认构造函数,或者已经alteast 扩展了默认构造函数)无论如何:

确保您没有删除 InitializeComponent();调用视图的构造函数。

如果在设置视图的 DataContext 之前没有此调用,NotifyPropertyChanged 事件将始终为 NULL。我花了大约 2 个小时试图弄清楚两个不同的 MVVM 用户控件之间有什么不同。我想我的头脑已经习惯了看到InitializeComponent();它没有登记它丢失了。我添加了后面和中提琴!

希望这能帮助像我这样的其他傻瓜!
干杯,
代码战士马洛

Ok I just finally experienced this issue, and there are NO complete answers on the Internet afaikt, so here is the missing piece that no one mentions (maybe because the assume that we are not complete morons and have NOT deleted the default constructor, or have alteast extended the default constructor) anyhow:

Make certain that you DID NOT delete the InitializeComponent(); call in the constructor of your View.

Without this call BEFORE you set DataContext of the view, NotifyPropertyChanged Event will ALWAYS BE NULL. I spent about 2 hours trying to figure out what was different between two different MVVM userControls. I guess my mind is so used to seeing InitializeComponent(); that it did not register that it was missing. I added that back and viola!

Hope This Helps Other Dummies Like Me!
Cheers,
Code Warrior Malo

零崎曲识 2024-09-11 19:12:16

它没有触发,因为集合引用没有改变,只是内容改变了。您需要集合的 Add() 方法来触发事件才能看到它。

It's not firing because the collection reference isn't changing, just the contents. You'd need the collection's Add() method to fire the event to be able to see it.

浴红衣 2024-09-11 19:12:16

看一下 System.Collections.ObjectModel.ObservableCollection。 http://msdn.microsoft.com/en-us/library/ms668604。 aspx

它可以像列表一样使用,但内置了当其内容发生变化时的事件。

have a look at System.Collections.ObjectModel.ObservableCollection. http://msdn.microsoft.com/en-us/library/ms668604.aspx

It can be used like a List but has events built in for when its contents change.

任性一次 2024-09-11 19:12:16

ObservableCollection 就是你的答案。如果要触发集合属性更改,则需要为要跟踪的每个属性实现 INotifyPropertyChanged。

ObservableCollection is your answer. If you want to fire on collection property changes, you'll need to implement INotifyPropertyChanged for each of the properties you'd like to track.

夕色琉璃 2024-09-11 19:12:16

您应该将事件侦听器添加到您的 _answers 集合中。不幸的是,List 不提供这样的事件。

建议将 _answers 作为 ObservableCollection 进行管理,并正确附加/分离 CollectionChanged 事件的事件处理程序,如下所示:

public ObservableCollection<string> Answers
{
    get { return _answers;  }
    set
    {
      // Detach the event handler from current instance, if any:
      if (_answers != null)
      {
         _answers.CollectionChanged -= _answers_CollectionChanged;
      }

      _answers = value;

      // Attatach the event handler to the new instance, if any:
      if (_answers != null)
      {
         _answers.CollectionChanged += _answers_CollectionChanged;
      }

      // Notify that the 'Answers' property has changed:
      onPropertyChanged("Answers");
    }
}

private void _answers_CollectionChanged(object sender,
NotifyCollectionChangedEventArgs e)
{
   onPropertyChanged("Answers");
}

You should add an event listener to your _answers collection. Unfortunately, List<T> doesn't provide such an event.

As a suggestion, manage _answers as an ObservableCollection<string>, and properly attach/detach an event handler for the CollectionChanged event, as follows:

public ObservableCollection<string> Answers
{
    get { return _answers;  }
    set
    {
      // Detach the event handler from current instance, if any:
      if (_answers != null)
      {
         _answers.CollectionChanged -= _answers_CollectionChanged;
      }

      _answers = value;

      // Attatach the event handler to the new instance, if any:
      if (_answers != null)
      {
         _answers.CollectionChanged += _answers_CollectionChanged;
      }

      // Notify that the 'Answers' property has changed:
      onPropertyChanged("Answers");
    }
}

private void _answers_CollectionChanged(object sender,
NotifyCollectionChangedEventArgs e)
{
   onPropertyChanged("Answers");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文