سؤال

هل هناك طريقة لمشاهدة رسم بياني كائن للتغييرات على أي كائن، وقم بعمل شيء بناء على هذا التغيير؟

دعنا نقول أن لدي ما يلي:

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

ما هي أفضل طريقة لتنفيذ نوع من نظام إعلام التغيير عبر جميع الكائنات؟ على سبيل المثال autosave، حيث يؤدي أي تغيير إلى تشغيل النظام لتسلسل Main صف دراسي.

يجب أن يكون لدي رمز الغراء في Main فئة مشاهدة BarItems للتغييرات، ربط تصل إلى PropertyChangedب هذا يبدو فوضوي بعض الشيء، والخطأ عرضت لي. هل هناك طريقة أفضل؟

هل كانت مفيدة؟

المحلول

بدلا من الكائنات التي تربط الممتلكات الخاصة بها غيرت الأحداث، ربما يمكنهم رفع حدث مشترك بدلا من ذلك. علي سبيل المثال:

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

يمكنك بعد ذلك إرفاق معالج حدث إلى Sharedchangeevent Sharedchangenotifient الثابت الذي سيتم إخطاره عند تغيير أي كائن مستمد من Sharedchangenotifier، مثل هذا:

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

نصائح أخرى

أنا فقط اقرأ وظيفة مدونة مثيرة للاهتمام حول هذه المسألة في http://www.lennybacon.com/reblinderfleckchangeTracking.aspx.

المنشور باللغة الألمانية، ولكن كما هو الحال في الغالب، يجب أن يكون موافق.

أتمنى أن يساعدك هذا!

الطريقة التي قمت بها في الماضي هي إنشاء فئة Changetracker منفصلة مع طريقة لتسجيل الكائنات فيها. داخل هذه الطريقة، استخدم الانعكاس لاستكشاف الكائن المسجل، والربط في أحداث على كل من خصائصها التي تنفذ inotifypropertychanged.

يمكنك بعد ذلك إضافة طرق إلى Changetracker لاستجواب الحالة، مثل ISDirty ()، أو حتى تنفيذ InotifyPropertychanged على ChangeTracker.

(تأكد من تنفيذ واستخدام Idisaberable على Changetracker، وإسقاط جميع معالجات الأحداث في ذلك الوقت).

يمكن أن يكون لديك نفس المعالج لجميع العناصر التي تنفذ الأحداث 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);
}

اتصل به باستخدام:

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

addToList<Foo>(ref fooItems, item);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top