WPF PropertyChanged 事件在更新后为 null 属性

WPF PropertyChanged event is null after updating property

我正在努力处理一些数据绑定。在我的主窗口中,我有 2 个按钮,它们数据绑定到 class "Properties" 中的 属性 Result - 严格用于保存我将用于数据绑定的属性。默认情况下,按钮是隐藏的,当我想让它们可见时,我只需将它们绑定的 Result 属性 设置为 "True"

我知道数据绑定正在工作,因为如果我将 属性 设置为静态值,则按钮可见/不可见。请参阅下面我的 XAML

<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                        <StackPanel.Resources>
                            <BooleanToVisibilityConverter x:Key="BoolToVis" />
                        </StackPanel.Resources>

                        <Button x:Name="btnBack" Height="25" Content="&lt;- Back" Visibility="{Binding Path=Result, Converter={StaticResource BoolToVis}, 
                            UpdateSourceTrigger=PropertyChanged}"  VerticalAlignment="Top" Width="75" Click="btnBack_Click" Margin="0,0,10,0" />

                        <Button x:Name="btnNext" Height="25" Content="Next ->" Visibility="{Binding Path=Result, Converter={StaticResource BoolToVis}, 
                            UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="75"  Click="btnNext_Click" Margin="10,0,0,0"/>
                    </StackPanel>

所以他们绑定到 "Result" 属性,而我的绑定中有 UpdateSourceTrigger=Propertychanged

在我的 "Properties" class 中,我有以下内容和 AM 实现 INotifyPropertyChanged

 bool _result;

    #endregion

    public bool Result {
        get
        {
            return _result;
        }
        set
        {
            _result = value;
            NotifyPropertyChanged("Result");

        }
    }

    #region EVENTS



    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }

但出于某种原因,当我将 属性 更改为 "True" 时,PropertyChanged 事件为空,因此该事件永远不会触发。

知道为什么会这样吗?可能是因为这段代码不在我的 ViewModel 中,而只是在一个单独的 class?

确保您已将 window 的 DataContext 设置为 Properties class 的一个实例,并且您没有设置任何父元素的 DataContext 属性 StackPanel 到其他东西,因为 DataContext 是继承的。

请参考以下示例代码。按钮在 3 秒延迟后确实如预期的那样可见:

public partial class MainWindow : Window
{
    private Properties _viewModel = new Properties();
    public MainWindow()
    {
        InitializeComponent();
        DataContext = _viewModel;

        this.Loaded += async (s, e) =>
        {
            await Task.Delay(3000);
            _viewModel.Result = true;
        };
    }
}

public class Properties : INotifyPropertyChanged
{
    bool _result;
    public bool Result
    {
        get
        {
            return _result;
        }
        set
        {
            _result = value;
            NotifyPropertyChanged("Result");

        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
}

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="300">
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
        <StackPanel.Resources>
            <BooleanToVisibilityConverter x:Key="BoolToVis" />
        </StackPanel.Resources>

        <Button x:Name="btnBack" Height="25" Content="&lt;- Back" Visibility="{Binding Path=Result, Converter={StaticResource BoolToVis}, 
                            UpdateSourceTrigger=PropertyChanged}"  VerticalAlignment="Top" Width="75" Margin="0,0,10,0" />

        <Button x:Name="btnNext" Height="25" Content="Next ->" Visibility="{Binding Path=Result, Converter={StaticResource BoolToVis}, 
                            UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="75"  Margin="10,0,0,0"/>
    </StackPanel>
</Window>