我有一个具有多个属性的类。当这些更改时,将引发 PropertyChangedEvent
。某些属性依赖于其他属性,因此当其中一个依赖项发生更改时,它会为自身和依赖于它的属性引发 PropertyChangedEvent
。
我的问题是,我已将 PropertyChangedEventHandler
附加到此类的实例。当一个属性依赖于另一个属性时,将多次调用此事件处理程序。有办法解决这个问题吗?
更新
一些代码,只是为了说明我在说什么:
private bool _foo;
private bool _bar;
public bool Foo
{
get { return _foo; }
set
{
_foo = value;
OnPropertyChanged("Foo");
OnPropertyChanged("Baz");
}
}
public bool Bar
{
get { return _bar; }
set
{
_bar = value;
OnPropertyChanged("Bar");
OnPropertyChanged("Baz");
}
}
public bool Baz
{
get
{
return Foo && Bar;
}
}
设置Foo
时,Baz
也会更改。如果我附加一个 PropertyChangedEventHandler
,这将在我设置 Foo
时被调用两次。我只想调用它一次。有解决办法吗?
最佳答案
您需要做的就是对这个问题进行片刻的逻辑思考以获得您的答案。你有以下情况:
public bool Foo
{
get { return _foo; }
set
{
_foo = value;
OnPropertyChanged("Foo");
OnPropertyChanged("Baz");
}
}
public bool Bar
{
get { return _bar; }
set
{
_bar = value;
OnPropertyChanged("Bar");
OnPropertyChanged("Baz");
}
}
public bool Baz
{
get
{
return Foo && Bar;
}
}
我的第一条评论是,如果您是一次多次引发您的 INotifyPropertyChanged.PropertyChanged
事件,那么您最好使用一个实现像这样,这将使您能够一次为任意数量的属性引发事件:
protected virtual void NotifyPropertyChanged(params string[] propertyNames)
{
if (PropertyChanged != null)
{
foreach (string propertyName in propertyNames)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
...
NotifyPropertyChanged("Foo", "Bar");
回到您的问题...让我们考虑一下您的要求:
- 需要在
Baz
的值发生变化时通知接口(interface)。
它的值可以在 Foo
或 Bar
属性值更改时更改...因此您需要在其中任何一个更改时通知界面,因为你有。
现在,@Franck 评论说您应该从 Property 1 的 setter 触发一个方法来更新 Property 2,通过更改将触发他自己的属性更改。让我们考虑一下……大概,您需要从 Foo
或 Bar
属性 setter 调用相同的方法才能使其工作。
然而,实际发生的情况是,当 Foo
和 Bar
值发生变化时,该方法将被调用两次,因此 INotifyPropertyChanged
通知仍将被调用两次,尽管现在来自 Baz
setter ...很明显,这没有改进。
但是,还有一种可能适合您的选择。为此,您需要添加一个辅助方法来更新 Foo
或 Bar
属性值并通知 代表
接口(interface):Baz
属性的 INotifyPropertyChanged
public void UpdateBaz(bool? foo, bool? bar)
{
if (foo != null) Foo = foo;
if (bar != null) Bar = bar;
OnPropertyChanged("Baz");
}
当然,要使其正常工作,您需要从两个属性处理程序中删除对 OnPropertyChanged("Baz")
的调用:
public bool Foo
{
get { return _foo; }
set { _foo = value; OnPropertyChanged("Foo"); }
}
public bool Bar
{
get { return _bar; }
set { _bar = value; OnPropertyChanged("Bar"); }
}
但是,如果您希望通过Binding
更新Foo
和Bar
属性,那么您将回到@Franck 的建议调用此方法两次并且两个属性分别更新。在那种情况下,您似乎只需要忍受 Baz
属性被通知两次。
关于c# - PropertyChangedEvent 多次触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23910471/