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

时间:2013-12-30 19:30:46

标签: c# event-handling inotifypropertychanged windows-forms-designer

假设我有这样的课程

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实例,我需要R视图来更改用户更改A的任何实例。

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

2 个答案:

答案 0 :(得分:9)

编辑:由于标签显示您已经了解INotifyPropertyChanged,因此对此问题的修改更加具体。

您需要在课程INotifyPropertyChanged和课程A中实施S。这样objectA只能通过一个属性进行设置,只要PropertyChanged中的属性发生变化,该属性就会在S上引发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 。添加后,订阅S的{​​{1}}个活动。然后更新了PropertyChanged的视图。例如:

R

答案 1 :(得分:0)

假设您有一个form1,其中您使用类R的实例来显示A类中的实例列表。您可以按edit并将类R的实例从类R实例发送到新表单。

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

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