2

In the following example the temp variable in RaisePropertyChanged() is always null. How do I subscribe to the event?

using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.CompilerServices;
using System.Text;

namespace TestProject.Module.BusinessObjects
{
    public class ContactPerson : INotifyPropertyChanged
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

        [NotMapped]
        public string PersonFullName
        {
            set
            {
                if (PersonFullName != value)
                {
                    var stringArray = value.Split();
                    var firstIndex = 0;
                    var lastIndex = stringArray.Length - 1;

                    if (lastIndex >= firstIndex)
                    {
                        FirstName = stringArray[firstIndex];
                    }
                    if (lastIndex > firstIndex)
                    {
                        LastName = stringArray[lastIndex];
                    }
                    RaisePropertyChanged();
                }
            }
            get
            {
                var sb = new StringBuilder();

                sb.Append(FirstName);
                sb.Append(" ");

                sb.Append(LastName);

                var stringArray = sb.ToString().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                var s = string.Join(" ", stringArray);

                return s;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public ContactPerson Clone()
        {
            var obj = new ContactPerson { FirstName = FirstName, LastName = LastName };

            return obj;
        }

        public override string ToString()
        {
            return PersonFullName;
        }

        protected void RaisePropertyChanged([CallerMemberName] string propertName = "")
        {
            var temp = PropertyChanged;
            if (temp != null)
            {
                temp(this, new PropertyChangedEventArgs(propertName));
            }
        }
    }
}

from reading This question it seems that PropertyChanged has not been subscribed to. How do I do this subscription?

Community
  • 1
  • 1
Kirsten
  • 15,730
  • 41
  • 179
  • 318

1 Answers1

2

Like this:

    private void Form1_Load(object sender, EventArgs e)
    {
        ContactPerson p = new ContactPerson();
        p.PropertyChanged += P_PropertyChanged;
    }

    private void P_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        throw new NotImplementedException();
    }

EDIT: expanding the sample code:

public partial class Form1 : Form
{
    ContactPerson p;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        p = new ContactPerson();
        p.PersonFullName = "Mary Jane";
        p.PropertyChanged += P_PropertyChanged;

        label1.Text = p.PersonFullName;

        // If you use databinding instead, you get the same result in this case.
        //label1.DataBindings.Add(new Binding("Text", p, "PersonFullName"));
    }

    private void P_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        label1.Text = p.PersonFullName;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        p.PersonFullName = "John Doe";
    }
}
jsanalytics
  • 13,058
  • 4
  • 22
  • 43
  • Ah, so the subscription happens in the form load. But why would I throw a NonImplementedException? – Kirsten Sep 08 '15 at 00:39
  • The subscription can happen whenever you need. The `Load` event is just a convenient place for this simple example. The exception throwing is just the default stub code inserted by Visual Studio, you can replace it by a `MessageBox.Show("Message here!")`, for instance, or any action you want to take in your actual code. – jsanalytics Sep 08 '15 at 00:44
  • Note to self. INotifyPropertyChanged needs to be implemented for the business object that the properties are being set in. Thus I should have had it in my Invoice Class instead of my Contact class. Also I should have called the method NotifyPropertyChanged instead of RaisePropertyChanged - to save my own confusion. – Kirsten Sep 08 '15 at 18:20
  • 1
    I would say `INotifyPropertyChanged` must be implemented for the business object the property belongs to. What happens if the property in a business object might be set by multiple other business objects? Are you going to implement `INotifyPropertyChanged` in all of them? And yes, the convention seems to be `NotifyPropertyChanged`. – jsanalytics Sep 08 '15 at 18:39