C# 属性更改多次发射
我有一个具有几个属性的类。当这些更改时,将引发一个C# 属性更改多次发射,c#,wpf,events,event-handling,C#,Wpf,Events,Event Handling,我有一个具有几个属性的类。当这些更改时,将引发一个PropertyChangedEvent。某些属性依赖于其他属性,因此当其中一个依赖项发生更改时,它会为自身以及依赖它的属性引发PropertyChangedEvent 我的问题是,我已将属性changedeventhandler附加到此类的实例。当一个属性依赖于另一个属性时,会多次调用此事件处理程序。有没有办法绕过这个问题 更新 一个小代码,只是为了说明我所说的: private bool _foo; private bool
PropertyChangedEvent
。某些属性依赖于其他属性,因此当其中一个依赖项发生更改时,它会为自身以及依赖它的属性引发PropertyChangedEvent
我的问题是,我已将属性changedeventhandler
附加到此类的实例。当一个属性依赖于另一个属性时,会多次调用此事件处理程序。有没有办法绕过这个问题
更新
一个小代码,只是为了说明我所说的:
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
也会改变。如果我附加了一个属性changedeventhandler
,当我设置Foo
时,它将被调用两次。我只想叫它一次。有什么好办法吗?在setter中插入一个值更改检查,如:
set
{
if(value != [yourfield])
{
yourfield = value;
OnPropertyChanged(Yourfield);
}
}
在setter中插入值更改检查,如:
set
{
if(value != [yourfield])
{
yourfield = value;
OnPropertyChanged(Yourfield);
}
}
你所需要做的就是对这个问题进行逻辑思考,然后得到答案。您有以下情况:
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));
}
}
}
回到你的问题上来。。。让我们考虑一下您的要求:
Baz
的值发生变化时,需要通知接口Foo
或Bar
属性值更改时,其值可以更改。。。因此,您需要在其中任何一个发生更改时通知接口,正如您所做的那样
现在,@frank评论说,您应该从属性1的setter触发一个更新属性2的方法,通过更改该方法将触发他自己的属性更改。让我们考虑一下。。。大概,您需要从Foo
或Bar
属性设置器调用相同的方法才能使其工作
但是,实际发生的情况是,当Foo
和Bar
值更改时,该方法将被调用两次,因此INotifyPropertyChanged
通知仍将被调用两次,尽管它现在来自Baz
setter。。。所以很明显,这并没有改善
然而,还有一个选择可能对你有用。为此,您需要添加一个助手方法,该方法将更新Foo
或Bar
属性值,并代表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"); }
}
但是,如果您希望通过
绑定更新Foo
和Bar
属性,那么您将返回@frank的建议,即调用此方法两次,并分别更新这两个属性。在这种情况下,您似乎只需要忍受两次通知Baz
属性。您所需要做的就是对这个问题进行逻辑思考片刻,以获得您的答案。您有以下情况:
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));
}
}
}
回到你的问题上来。。。让我们考虑一下您的要求:
当Baz
的值发生变化时,需要通知接口
当Foo
或Bar
属性值更改时,其值可以更改。。。因此,您需要在其中任何一个发生更改时通知接口,正如您所做的那样
现在,@frank评论说,您应该从属性1的setter触发一个更新属性2的方法,通过更改该方法将触发他自己的属性更改。让我们考虑一下。。。大概,您需要从Foo
或Bar
属性设置器调用相同的方法才能使其工作
但是,实际发生的情况是,当Foo
和Bar
值更改时,该方法将被调用两次,因此INotifyPropertyChanged
通知仍将被调用两次,尽管它现在来自Baz
setter。。。所以很明显,这并没有改善
然而,还有一个选择可能对你有用。为此,您需要添加一个助手方法,该方法将更新Foo
或Bar
属性值,并代表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"); }
}
但是,如果您希望通过绑定更新Foo
和Bar
属性,那么您将返回@frank的建议,即调用此方法两次,并分别更新这两个属性。在这种情况下,您似乎只能忍受Baz
属性被通知两次。我觉得这完全合乎逻辑。您不应该禁用所有这些事件:当属性发生更改时,它应该触发更改事件。你需要如何处理它?EventHandler中发生了什么?为什么要忽略其他处理程序?不应引发从另一个处理程序更改的另一个属性。您应该从属性1的setter触发一个方法来更新属性2 w