Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 观察对象图的变化_C#_.net_Design Patterns_Inotifypropertychanged - Fatal编程技术网

C# 观察对象图的变化

C# 观察对象图的变化,c#,.net,design-patterns,inotifypropertychanged,C#,.net,Design Patterns,Inotifypropertychanged,有没有一种方法可以观察对象图中任何对象的变化,并根据这种变化做一些事情 假设我有以下几点: public class Main:INotifyPropertyChanged { public ObservableCollection<Foo> FooItems { get; } public ObservableCollection<Bar> BarItems { get; } } public class Foo:INotifyPropertyChan

有没有一种方法可以观察对象图中任何对象的变化,并根据这种变化做一些事情

假设我有以下几点:

public class Main:INotifyPropertyChanged
{
    public ObservableCollection<Foo> FooItems { get; }
    public ObservableCollection<Bar> BarItems { get; }
}

public class Foo:INotifyPropertyChanged

public class Bar:INotifyPropertyChanged
{
    public ObservableCollection<Other> OtherItems { get; }
}

public class Other:INotifyPropertyChanged
public类Main:INotifyPropertyChanged
{
公共ObservableCollection FooItems{get;}
公共可观测收集项目{get;}
}
公共类Foo:INotifyPropertyChanged
公共类栏:INotifyPropertyChanged
{
公共ObservableCollection其他项{get;}
}
公共类其他:INotifyPropertyChanged
在所有对象中实现某种更改通知系统的最佳方式是什么?例如,autosave,其中任何更改都会触发系统序列化
Main


我是否应该在
Main
类中使用胶水代码来监视
BarItems
的更改,并连接到它们的
属性更改
?这看起来有点混乱,我很容易出错。有更好的办法吗?

我刚刚在

这篇文章是用德语写的,但大部分是代码,应该没问题


希望这有帮助

与其让对象引发自己的属性更改事件,不如让对象引发共享事件。例如:

public class SharedChangeNotifier
{
    public static event EventHandler<DataChangedEventArgs> SharedChangeEvent;

    protected void RaiseChangeEvent()
    {
        if (SharedChangeNotifier.SharedChangeEvent != null)
        {
            SharedChangeNotifier.SharedChangeEvent(
                this, new DataChangedEventArgs());
        }
    }
}

public class Foo : SharedChangeNotifier
{
    public int MyProperty
    {
        get { ... }
        set
        {
            ...
            RaiseChangeEvent();
        }
    }
}

我过去的做法是创建一个单独的ChangeTracker类,并使用一个方法将对象注册到该类中。在该方法中,使用反射来探索已注册的对象,并钩住实现INotifyPropertyChanged的每个属性上的事件

然后,您可以向ChangeTracker添加方法来查询状态,例如IsDirty(),甚至可以在ChangeTracker上实现INotifyPropertyChanged


(请确保在ChangeTracker上实现并使用IDisposable,同时删除所有事件处理程序)。

对于实现INotifyPropertyChanged事件的所有项目,您可以使用相同的处理程序:

foreach (INotifyPropertyChanged obj in FooItems)
    obj.PropertyChanged+= this.modified;

// likewise for bar items, and when items are added

private void modified(object sender, EventArgs args)
{
    this.Save();
}
编辑>在添加项目时执行相同操作:

private void addToList<T>(ref List<T> l, T item) where T : INotifyPropertyChanged
{
    item.PropertyChanged += this.modified;
    l.Add(item);
}
private void addToList(参考列表l,T项),其中T:INotifyPropertyChanged
{
item.PropertyChanged+=此.modified;
l、 增加(项目);
}
使用以下命令调用它:

Foo item = new Foo();
List<Foo> fooItems = new List<Foo>();

addToList<Foo>(ref fooItems, item);
Foo item=newfoo();
List fooItems=新列表();
addToList(参考项目,项目);

我可以做到这一点,但我也使用INotifyPropertyChanged接口进行数据绑定,因此最好使用已有的接口。但是我会记住这一点。当从FooItems中添加或删除项目时会发生什么情况?
Foo item = new Foo();
List<Foo> fooItems = new List<Foo>();

addToList<Foo>(ref fooItems, item);