观察对象图的变化

发布于 2024-07-25 18:25:04 字数 675 浏览 10 评论 0原文

有没有办法观察对象图以了解任何对象的更改,并根据该更改执行某些操作?

假设我有以下内容:

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

在所有对象上实现某种更改通知系统的最佳方法是什么? 例如,自动保存,任何更改都会触发系统序列化 Main 类。

我是否应该在 Main 类中使用粘合代码来监视 BarItems 的更改,并连接到它们的 PropertyChanged ? 这看起来有点混乱,而且对我来说很容易出错。 有没有更好的办法?

Is there a way to watch an object graph for changes on any object, and do something based on that change?

Lets say I have the following:

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

What would be the best way to implement some sort of change notification system across all objects? For example an autosave, where any change would trigger the system to serialize the Main class.

Should I have glue code in the Main class watching the BarItems for changes, hooking up to their PropertyChanged? This seems a bit messy, and error prone to me. Is there a better way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

幸福丶如此 2024-08-01 18:25:04

也许它们可以引发共享事件,而不是引发自己的属性更改事件的对象。 例如:然后

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();
        }
    }
}

,您可以将事件处理程序附加到静态 SharedChangeNotifier 的 SharedChangeEvent,以便在从 SharedChangeNotifier 派生的任何对象发生更改时收到通知,如下所示:

SharedChangeNotifier.SharedChangeEvent += (sender, args) => {
    DoWhatever();
};

Rather than objects raising their own property changed events, perhaps they could raise a shared event instead. For example:

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();
        }
    }
}

You could then attach an event handler to the static SharedChangeNotifier's SharedChangeEvent to be notified whenever any object deriving from SharedChangeNotifier is changed, like this:

SharedChangeNotifier.SharedChangeEvent += (sender, args) => {
    DoWhatever();
};
鱼窥荷 2024-08-01 18:25:04

我刚刚在 http://www.lennybacon.com/ReBlinderFleckChangeTracking.aspx 上阅读了一篇关于该问题的有趣博客文章

这篇文章是德语的,但由于它主要是代码,所以应该没问题。

希望这可以帮助!

I just read an interesting blog post on that issue at http://www.lennybacon.com/ReBlinderFleckChangeTracking.aspx

The post is in German, but as it's mostly code, it should be OK.

Hope this helps!

三生殊途 2024-08-01 18:25:04

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

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

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

The way I have done it in the past was to create a separate ChangeTracker class with a method to Register objects into it. Inside that method, use reflection to explore the registered object, and hook into events on each of its properties that implements INotifyPropertyChanged.

You can then add methods to the ChangeTracker to interrogate the state, e.g. IsDirty(), or even implement INotifyPropertyChanged on the ChangeTracker.

(Be sure to implement and use IDisposable on the ChangeTracker, and drop all the event handlers at that time).

星光不落少年眉 2024-08-01 18:25:04

您可以对实现 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();
}

edit> 要在添加项目时执行相同操作:

private void addToList<T>(ref List<T> l, T item) where T : INotifyPropertyChanged
{
    item.PropertyChanged += this.modified;
    l.Add(item);
}

使用以下命令调用它:

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

addToList<Foo>(ref fooItems, item);

You could have the same handler for all items that implement INotifyPropertyChanged events:

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();
}

edit> To do the same when an item is added:

private void addToList<T>(ref List<T> l, T item) where T : INotifyPropertyChanged
{
    item.PropertyChanged += this.modified;
    l.Add(item);
}

call it using:

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

addToList<Foo>(ref fooItems, item);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文