WPF PropertyChanged event is null after updating property

6.7k views Asked by At

I'm struggling with some databinding. In my MainWindow I have 2 buttons which are databound to a property Result in a class "Properties" - strictly for holding properties that I will be using for databinding. The buttons are hidden by default, and when I want them to become visible I simply set Result property that they are bound to to "True"

I know the databinding is working because if I set the property to a static value, the buttons are visible / not visible. See below for my 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>

So they are bound to "Result" property, and I have UpdateSourceTrigger=Propertychangedin my binding.

In my "Properties" class I have the below and AM implementing 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));
        }
    }

But for some reason when I change the property to "True" the PropertyChanged Event is null and therefore the event never fires.

Any idea as to why this is happening? Could it be because this code isn't in my ViewModel and just in a separate class?

1

There are 1 answers

2
mm8 On BEST ANSWER

Make sure that you have set the DataContext of the window to an instance of your Properties class and that you don't set the DataContext property of any parent element of the StackPanel to something else because the DataContext is inherited.

Please refer to the following sample code. The Buttons do become visible as expected after the 3 second delay:

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>