Manthan
Manthan

Reputation: 383

Notify One object when a property of another object changes

I have a parent object called Page that has a List of objects called Control:

public class Page
{
   List<CustomControl> controls {get;set;}
}

The CustomControl class has the following defintion:

public class CustomControl
{
 string Name {get;set;}
 string Value {get;set;}
}

Say for instance the Page class has two CustomControls A and B. Is it possible to Notify Custom Control B when the property Value of Custom Control A changes so that it can change some of its properties.

I was thinking of implementing the INotifyPropertyChanged event on the CustomControl class now how do I notify an instance of the CustomControl when another instance of the same class has some property of its Modified.

Upvotes: 6

Views: 10967

Answers (2)

Kamal Sukla
Kamal Sukla

Reputation: 171

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PropertyNotificatioDemo

{

    class Program

    {

        static void Main(string[] args)

        {

            PropertyNotification notification = new PropertyNotification();   //Create an object of PropertyNotification class.

            //Create EmployeeValueChange handler.

            PropertyNotification.EmployeeValueChange += new PropertyNotification.EmployeeNameHandler(PropertyNotification_EmployeeValueChange);



            //Display a message.

            Console.Write("Enter Value  :  ");

            //Read a value and initilize it in property.

            notification.EmployeeName = Console.ReadLine();

        }



        //Handler for property notification is created.

        static void PropertyNotification_EmployeeValueChange(object sender, EventArgs e)

        {

            Console.WriteLine("Employee name is changed."+sender);

        }

    }



    public class PropertyNotification

    {

        //Create a private variable which store value.

        private static string _employeeName;

        //Create a delegate of named EmployeeNamed=Handler

        public delegate void EmployeeNameHandler(object sender, EventArgs e);



        //Create a event variable of EmployeeNameHandler

        public static event EmployeeNameHandler EmployeeValueChange;



        //Create a static method named OnEmployeeNameChanged

        public static void OnEmployeeNameChanged(EventArgs e)

        {

            if (EmployeeValueChange != null)

                EmployeeValueChange(_employeeName, e);

        }



        //Create a property EmployeeName

        public string EmployeeName

        {

            get

            {

                return _employeeName;

            }

            set

            {

                //Check if value of property is not same.

                if (_employeeName != value)

                {

                    OnEmployeeNameChanged(new EventArgs());

                    _employeeName = value;

                }

            }

        }

    }

}

Upvotes: 0

Ani
Ani

Reputation: 113442

public class CustomControl : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name == value) return;
            _name = value;
            PropertyChanged(this, new PropertyChangedEventArgs("Name"));
        }
    }

    private string _value;
    public string Value
    {
        get { return _value; }
        set
        {
            if (_value == value) return;

            _value = value;
            PropertyChanged(this, new PropertyChangedEventArgs("Value"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    internal virtual void OnSiblingInPagePropertyChanged(object sender, PropertyChangedEventArgs args)
    {

    }
}

public class CustomControlObservableColletion : ObservableCollection<CustomControl>
{
    // Required because, by default, it is not possible to find out which items
    // have been cleared when the CollectionChanged event is fired after a .Clear() call.
    protected override void ClearItems()
    {
        foreach (var item in Items.ToList())
            Remove(item);
    }

}

public class Page
{
    public IList<CustomControl> Controls { get; private set; }

    public Page()
    {
        var controls = new CustomControlObservableColletion();
        controls.CollectionChanged += OnCollectionChanged;
        Controls = controls;
    }

    private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
                RegisterControls(e.NewItems);
                break;

            case NotifyCollectionChangedAction.Replace:
                RegisterControls(e.NewItems);
                DeRegisterControls(e.OldItems);
                break;

            case NotifyCollectionChangedAction.Remove:
                DeRegisterControls(e.OldItems);
                break;
        }
    }

    private void RegisterControls(IList controls)
    {
        foreach (CustomControl control in controls)
            control.PropertyChanged += OnControlPropertyChanged;
    }

    private void DeRegisterControls(IList controls)
    {
        foreach (CustomControl control in controls)
            control.PropertyChanged -= OnControlPropertyChanged;
    }

    private void OnControlPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        foreach (var control in Controls.Where(c => c != sender))
            control.OnSiblingInPagePropertyChanged(sender, e);
    }
}

Upvotes: 5

Related Questions