c# - PropertyChangedEvent 多次触发

标签 c# wpf events event-handling

我有一个具有多个属性的类。当这些更改时,将引发 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");

回到您的问题...让我们考虑一下您的要求:

  1. 需要在Baz的值发生变化时通知接口(interface)。

它的值可以在 FooBar 属性值更改时更改...因此您需要在其中任何一个更改时通知界面,因为你有。

现在,@Franck 评论说您应该从 Property 1 的 setter 触发一个方法来更新 Property 2,通过更改将触发他自己的属性更改。让我们考虑一下……大概,您需要从 FooBar 属性 setter 调用相同的方法才能使其工作。

然而,实际发生的情况是,当 FooBar 值发生变化时,该方法将被调用两次,因此 INotifyPropertyChanged 通知仍将被调用两次,尽管现在来自 Baz setter ...很明显,这没有改进。

但是,还有一种可能适合您的选择。为此,您需要添加一个辅助方法来更新 FooBar 属性值通知 代表 Baz 属性的 INotifyPropertyChanged 接口(interface):

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 更新FooBar 属性,那么您将回到@Franck 的建议调用此方法两次并且两个属性分别更新。在那种情况下,您似乎只需要忍受 Baz 属性被通知两次。

关于c# - PropertyChangedEvent 多次触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23910471/

相关文章:

c# - MathNET 矩阵转换

c# - 在 VSTO 和 WPF 应用程序中未调用 SystemEvents.PowerModeChanged 事件处理程序

android - 如何在膨胀 View 上获取 OnClick 事件

c++ - Boost Circular Buffer,如何让它在填充时调用一些函数?

events - jQuery — 页面上的每个元素仅触发一次实时事件?

c# - C# 中路径、多边形、面积和线的可继承 Java 类等效项

c# - 如何在 wpf c# 中播放双音频电影

c# - HTTPWebRequest.GetResponse() 因通过透明代理的经过身份验证的请求而失败

c# - 矩形角度属性

c# - 如何从 View 模型将 Func<T,T,T> 绑定(bind)到 XAML 中的依赖属性?