C# - RaisePropertyChanged 多次调用并抛出 stackoverflow 异常

标签 c# wpf xaml

我对 WPF 相当陌生。我的应用程序中有以下单选按钮

<Viewbox Height="30">
     <RadioButton Content="B1" GroupName="InputBelt" IsChecked="{Binding RBChecked, Mode=TwoWay, FallbackValue=True}" VerticalAlignment="Center"/>
</Viewbox>
<Viewbox Height="30">
     <RadioButton Content="B2" GroupName="InputBelt" IsChecked="{Binding RBChecked, Converter={StaticResource boolconverter}, Mode=TwoWay}" VerticalAlignment="Center"/>
</Viewbox>

我已经在xaml文件中定义了数据上下文

<Window.DataContext>
    <vm:TestViewModel />
</Window.DataContext>

问题是当页面第一次加载时,一切都很好。但是,当我转到应用程序中的其他页面并返回到此页面时,应用程序由于 stackoverflow 异常而崩溃。

我什至尝试在单选按钮标记中本地添加数据上下文,但它也不起作用。

属性结构如下。

private bool _bRBChecked;
public bool RBChecked
{
    get { return _bRBChecked; }
    set
    {
        _bRBChecked = value;
        RaisePropertyChanged("RBChecked");
    }
}

经过进一步调查,我发现绑定(bind)属性的 RaisePropertyChanged 被调用了太多次。仅当属性绑定(bind)到单选按钮时才会出现此问题。我还有其他控件,它们与同一页面中的其他属性进行双向绑定(bind),并且似乎工作正常。

现在我已经尝试了另一个 stackoverflow 问题中建议的以下修复,它似乎有效。

set
{
    if (_bRBChecked != value)
    {
        _bRBChecked = value;
        RaisePropertyChanged("RBChecked");
    }
}

但我想知道此问题的根本原因以及为什么该属性被设置如此多次,并在可能的情况下找到任何替代解决方案。如果我遗漏了什么,请告诉我。 任何见解都是非常值得赞赏的。

最佳答案

您的更改通知不受递归保护。属性 A 改变属性 B,属性 B 的改变又改变属性 A...

一个简单的解决方案是这样的:

set
{
    if(value != _bRBChecked){
      _bRBChecked = value;
      RaisePropertyChanged("RBChecked");
    }
}

在告诉大家之前,只需检查该值是否确实发生了更改。此模式在 Examples 中明确使用。我 90% 确定依赖属性具有类似的递归保护,但这不是我第一次错。

关于C# - RaisePropertyChanged 多次调用并抛出 stackoverflow 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59368441/

相关文章:

xaml - 如何在 XAML ListBox 中使用多重绑定(bind)?

c# - 绑定(bind)数据网格后,项目集合必须为空

c# - 正确使用 Async/Await

c# - 如果这个类没有 Dispose 方法,它如何实现 IDisposable?

WPF错误消息: Partial declaration must not specify different base classes

c# - WPF 数据网格延迟加载

wpf - 如何将控件绑定(bind)到 ViewModel(MVVM 模式)中的 XmlDocument 元素?

c# - 带有 linq lambda 表达式的查询列表

c# - 如何使用 Moq 修改模拟方法的调用参数?

c# - WPF 拖放 - 从 DragEventArgs 获取原始源信息