Уведомлять один объект при изменении свойства другого объекта
у меня есть родительский объект под названием Page, который имеет список объектов под названием Control:
public class Page
{
List<CustomControl> controls {get;set;}
}
класс CustomControl имеет следующее определение:
public class CustomControl
{
string Name {get;set;}
string Value {get;set;}
}
скажем, например, класс Page имеет два CustomControls A и B. Можно ли уведомить пользовательский элемент управления B, когда значение свойства пользовательского элемента управления a изменяется, чтобы он мог изменить некоторые из своих свойств.
Я думал о реализации события INotifyPropertyChanged на Класс CustomControl теперь как уведомить экземпляр CustomControl, когда другой экземпляр того же класса имеет некоторое свойство его измененного.
2 ответов
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);
}
}
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;
}
}
}
}
}