如何传播集合中对象的属性更改通知



假设我有这样的类

public class R
{
    protected string name;
    protected List<S> listOfObjectS;
}
public class S
{
    private string name, ID;
    private A objectA;
}
public class A
{
    private string name;
    private int count;
}

如果用户打开了两个视图,一个显示R的实例,另一个允许用户修改A的实例,我需要在用户更改任何A实例时更改R的视图。

如果用户更改了A实例的属性,传播该更改(通过S实例)以使R的所有实例都显示A的新状态的最佳方法是什么?

编辑:彻底修改此答案以更具体地针对问题,因为标签显示您已经了解INotifyPropertyChanged

您需要在类 A 和类 S 中实现INotifyPropertyChanged。使其只能通过一个属性来设置objectA该属性将在 S 上引发 PropertyChanged 事件,只要在 A 中更改属性。例:

public class A : INotifyPropertyChanged
{
    private string name;
    public string Name
    {
        get { return name; }
        set { name = value; OnPropertyChanged("Name"); }
    }
    private int count;
    public int Count
    {
        get { return count; } 
        set { count = value; OnPropertyChanged("Count"); }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

。和类S...

public class S : INotifyPropertyChanged
{
    private string name, ID;
    private A objectA;
    public A ObjectA
    {
        get { return objectA; }
        set
        {
            var old = objectA;
            objectA = value;
            // Remove the event subscription from the old instance.
            if (old != null) old.PropertyChanged -= objectA_PropertyChanged;
            // Add the event subscription to the new instance.
            if (objectA != null) objectA.PropertyChanged += objectA_PropertyChanged;
            OnPropertyChanged("ObjectA");
        }
    }
    void objectA_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        // Propagate the change to any listeners. Prefix with ObjectA so listeners can tell the difference.
        OnPropertyChanged("ObjectA." + e.PropertyName);
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

对于类R,请使用 ObservableCollection<S> 而不是 List<S> ,并订阅其 CollectionChanged 事件,并监视何时添加或删除对象以listOfObjectS。添加后,订阅 SPropertyChanged事件。然后更新了R的视图。例:

public class R
{
    protected string name;
    protected System.Collections.ObjectModel.ObservableCollection<S> ListOfObjectS { get; private set; }
    public R()
    {
        // Use ObservableCollection instead.
        ListOfObjectS = new ObservableCollection<S>();
        // Subscribe to all changes to the collection.
        ListOfObjectS.CollectionChanged += listOfObjectS_CollectionChanged;
    }
    void listOfObjectS_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            // When items are removed, unsubscribe from property change notifications.
            var oldItems = (e.OldItems ?? new INotifyPropertyChanged[0]).OfType<INotifyPropertyChanged>();
            foreach (var item in oldItems)
                item.PropertyChanged -= item_PropertyChanged;
        }
        // When item(s) are added, subscribe to property notifications.
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            var newItems = (e.NewItems ?? new INotifyPropertyChanged[0]).OfType<INotifyPropertyChanged>();
            foreach (var item in newItems)
                item.PropertyChanged += item_PropertyChanged;
        }
        // NOTE: I'm not handling NotifyCollectionChangedAction.Reset.
        // You'll want to look into when this event is raised and handle it
        // in a special fashion.
    }
    void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName.StartsWith("ObjectA."))
        {
            // Refresh any dependent views, forms, controls, whatever...
        }
    }
}

假设您有一个 form1,您可以在其中使用类 R 的实例来显示类 A 中的实例列表。然后按编辑,然后将同一类 A 的实例从类 R 实例发送到新窗体。

这将是对 R 实例中包含的对象的引用,因此会在 form2 中更新。您唯一需要做的就是刷新 form1 列表中的类 A 实例。

解释一下:当您使用类的对象实例调用窗体或方法时,这将创建一个引用,而不是克隆,因此可以从第二个 form2 更新。

相关内容

  • 没有找到相关文章

最新更新