2

I have the following XAML in my WPF project:

<Window x:Class="DataBindToLocalVars.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <TextBox x:Name="txt2" HorizontalAlignment="Left" Height="23" Margin="150,94,0,0" TextWrapping="Wrap" Text="{Binding Path=value1}" VerticalAlignment="Top" Width="120"/>
    <TextBox x:Name="txt1" HorizontalAlignment="Left" Height="23" Margin="150,140,0,0" TextWrapping="Wrap" Text="{Binding Path=value2}" VerticalAlignment="Top" Width="120"/>
    <Label Content="Value 2" HorizontalAlignment="Left" Margin="107,91,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.577,-0.602"/>
    <Label Content="Value1" HorizontalAlignment="Left" Margin="107,145,0,0" VerticalAlignment="Top"/>

</Grid>

And the following code in my code-behind file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace DataBindToLocalVars
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public string value1
    {
        get { return value1; }
        set
        {
            value1 = value;
            this.NotifyPropertyChange("value1");
        }
    }
    public string value2 {
        get { return value2; }
        set {
        value2 = value;
        this.NotifyPropertyChange("value2");
    } }
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;

        value1 = "20";
        value2 = "40"; 
    }

    public void NotifyPropertyChange(string propName)
    {
        this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
}
}

I am implementing the INotifyPropertyChange interface to be notified when the properties value1 and value2 change. But running this code gives me a stack overflow exception. Why is this?

2 Answers 2

2

This is your cause:

public string value1
{
    get { return value1; }
    set
    {
        value1 = value;
        this.NotifyPropertyChange("value1");
    }
}

Your property getters and setters are entirely recursive (they result in calls to themselves).

Idiomatic C# uses PascalCasing for property names, so how about:

private string value1;

public string Value1
{
    get { return value1; }
    set
    {
        value1 = value;
        this.NotifyPropertyChange("Value1");
    }
}

Here the getter and setter uses the private value1 field.

You also have an issue in your INotifyPropertyChanged implementation. When an event has no subscribers, then the handler will be null. You need to guard against this or you'll get a NullReferenceException:

public void NotifyPropertyChange(string propName)
{
    var handler = PropertyChanged;
    if (handler != null) handler(this, new PropertyChangedEventArgs(propName));
}
Sign up to request clarification or add additional context in comments.

4 Comments

This is not working for me. I am now getting NullReferenceException in my NotifyPropertyChange() event handler.
@tutiplain you have two bugs. I've added a fix for that one.
This solution works, but I don't understand why I must check if PropertyChanged is null. All the event handling examples I've checked out so far do it. Why would PropertyChanged ever be null? I know I'm not explicitly assigning to it, but that by the time the event is raised its value would not be null.
When there are no subscribers to an event the delegate will be null. This check should be present on raising any event, it's not specific to PropertyChanged.
0

Of course it is you are setting the property with in the property you need to set a private member with in the property then you raise property changed so Binding objects will be notified to sample it.

Firstly please use capital letters.

   private int _value1;
   public int Value1
   {
      get{ return _value1; }
      set
      { 
          _value1 = value;
          NotifyPropertyChange("Value1"); 
      }
   }

EDIT :

What .Net version are you running on .? I remember an issue in .net 4 where you had to do this .

 public event PropertyChangedEventHandler PropertyChanged = delelgate{};

So the event won't be null before the binding subscribes to it.

1 Comment

Not working, either. NotifyPropertyChange now throws a NullReferenceException.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.