Question

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication3
{
    class Cls : INotifyPropertyChanged
    {
        private string my;
        public  string MyProperty
        {
            get
            {
                return my;
            }
            set
            {
                my = value;
                PropertyChanged(this, new PropertyChangedEventArgs("MyProperty")); 
            }

        }

        public Cls()
        {
            MyProperty = "Hello";
        }

        public void print()
        {
            Console.WriteLine(MyProperty);
        }

        protected virtual void OnPropertyChanged(string name)
        {
        }

        public event PropertyChangedEventHandler PropertyChanged;

    }

    class Program
    {
        static void Main(string[] args)
        {
            Cls s = new Cls();
            s.print();
        }
    }
}

When I run this code, it gives:

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.

When I do not use INotifyPropertyChanged it works fine. I do not understand cause of problem.

Was it helpful?

Solution

There is noone listening to PropertyChanged, which will then be null when trying to call it. Use an OnPropertyChanged method instead:

private void OnPropertyChanged(string propertyName){
    var handler = PropertyChanged;
    if (handler != null)
        handler(this, new PropertyChangedEventArgs(propertyName));

    // With C# 6 this can be replaced with
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

public  string MyProperty
{
    get { return my; }
    set
    {
       if (my == value)
           return;

        my = value;
        OnPropertyChanged("MyProperty");
    }
}

To avoid it being null you have to subscribe to it, for instance from your main method:

static void Main(string[] args){
    Cls s = new Cls();
    s.PropertyChanged += (sender, args) => MessageBox.Show("MyProperty changed!");
    s.print();
}

which is a fancy way of writing

static void Main(string[] args){
    Cls s = new Cls();
    s.PropertyChanged += ShowMessage;
    s.print();
}

private void ShowMessage(object sender, PropertyChangedEventArgs args){
    MessageBox.Show("MyProperty changed!");
}

Whatever is more clear to you.
You can read more about events here

OTHER TIPS

If nothing has subscribed to the PropertyChanged event, firing the event will throw a NullReferenceException. You need to do a null check before firing the event, like this:

if (PropertyChanged != null)
{
    PropertyChanged(this, new PropertyChangedEventArgs("MyProperty"));
}

The PropertyChanged delegate has no listeners. You should always check that a delegate isn't null before you raise it.

if (PropertyChanged != null)
{
    PropertyChanged(this, new PropertyChangedEventArgs("MyProperty"));
}

Also, judging from your code, you probably meant for OnPropertyChanged to be called when the property is changed. In order to do so, you should add event listener to PropertyChanged, and call OnPropertyChanged in the listener. You can do it by adding the following code:

//Old ctor
public Cls()
{
    PropertyChanged += new PropertyChangedEventHandler(Cls_PropertyChanged); //Register the event handler
    MyProperty = "Hello";
}

void Cls_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    OnPropertyChanged(e.PropertyName); //Call your method
}

I received the error in my 'viewmodel' class because i omitted the INotifyPropertyChanged interface declaration.

so from something like this

public class viewmodel
   {}

to this

public class viewmodel: INotifyPropertyChanged
 {}

fixed it.


Would not have been helpful to the OP but an oversight that someone else might make?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top