Elegant way to implement INotifyPropertyChanged across many controls

I'm building a WPF application and I'm slowly uncovering some of the joys and also the frustrations of using WPF. My latest question involves updating the UI using INotifyPropertyChanged

My app has stacked UserControls with each UserControl containing multiple controls, so overall there are hundreds of controls which update every second providing live data. In order to update all controls I'm using something similar to below which does currently work as intended.

namespace ProjectXAML
{
    public partial class ProjectX : UserControl, INotifyPropertyChanged
    {


#region Declare Getter/Setter with INotifyPropertyChanged groupx3

        private string m_group1Text1;
        public string group1Text1
        {
            get
            {
                return m_group1Text1;
            }
            set
            {
                m_group1Text1 = value;
                NotifyPropertyChanged("group1Text1");
            }
        }

        private string m_group1Text2;
        public string group1Text2
        {
            get
            {
                return m_group1Text2;
            }
            set
            {
                m_group1Text2 = value;
                NotifyPropertyChanged("group1Text2");
            }
        }

        private string m_group2Text1;
        public string group2Text1
        {
            get
            {
                return m_group2Text1;
            }
            set
            {
                m_group2Text1 = value;
                NotifyPropertyChanged("group2Text1");
            }
        }

        private string m_group2Text2;
        public string group2Text2
        {
            get
            {
                return m_group2Text2;
            }
            set
            {
                m_group2Text2 = value;
                NotifyPropertyChanged("group2Text2");
            }
        }

        private string m_group3Text1;
        public string group3Text1 
        { 
            get
            {
                return m_group3Text1;
            }
            set
            {
                m_group3Text1 = value;
                NotifyPropertyChanged("group3Text1");
            }
        }

        private string m_group3Text2;
        public string group3Text2
        {
            get
            {
                return m_group3Text2;
            }
            set
            {
                m_group3Text2 = value;
                NotifyPropertyChanged("group3Text2");
            }
        }

 #endregion

 #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        /// Notifies the property changed.
        private void NotifyPropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
 #endregion

}
}

My questions are:

  1. Is there a more elegant way to raise PropertyChanged events for lots of controls rather than lots of get/set code?

  2. Is there a way to raise 1 PropertyChanged event covering the whole UserControl containing multiple controls instead of a separate event for every control? Is there a better method than what I'm attempting?

Answers


In strict reference to this part of your question..."Is there a way to raise 1 PropertyChanged event covering the whole UserControl containing ".

Yes, you can raise a PropertyChanged notification which says all my properties on my object are updated.

Use:

NotifyPropertyChanged(null);

then this informs the listener of INotifyPropertyChanged that all properties have changed on an object.

This isn't normally used...and can be abused....and cause inefficient updates e.g. if you were only changing a few properties and used that.

But you could argue the case for using it if you have lots of properties in your object, that you were always changing anyway at the same time...and you wanted to collapse lots of individual notifications into 1 that was raised after you had modified all properties.

Example use case (i.e. presumes you are updating all your groups in some way):

void UpdateAllGroupTextProperties()
{
    group1Text1 = "groupA";
    group1Text2 = "groupA2";
    group2Text1 = "groupB";
    group2Text2 = "groupB2";
    group3Text1 = "groupC";
    group3Text2 = "groupC2";
    NotifyPropertyChanged(null);
}

Use the design pattern model view controler. So the model will raise the changes for you. Together with MVVM the controls will see with its dependency objects the changes and view them automatically.


For point 1 if you are using VS 2012 you can do the below

private void SetProperty<T>(ref T field, T value, [CallerMemberName] string name = "")
{
    if (!EqualityComparer<T>.Default.Equals(field, value))
    {
        field = value;
        var handler = PropertyChanged;
        if (handler != null)
        {
          handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

and then you can use your set property method without having to hard code the name of the properties.

Note the above code is an except of the below link http://danrigby.com/2012/03/01/inotifypropertychanged-the-net-4-5-way/


Need Your Help

Did P/Invoke environment change in .NET 4.0?

delphi .net-4.0 pinvoke

I've started upgrading a .NET 2.0 WinForms application to .NET 4.0. Well, OK, the upgrade process was just a matter of switching platform target, but making it actually work. I assumed that's all...

MultiBinding to static property and non-static - listview not updating

wpf listview static observablecollection multibinding

I've got a static ObservableCollection> named HeaderColorPairs in the non-static class ColorManager (singleton).

rails tutorial 10.3.3 feed_item failing test

ruby-on-rails rspec railstutorial.org

I get down to 10.43 without errors, however the following errors occurred after attempting to create a micropost. The tutorial says this would happen and that I would need to go and enter a blank a...