通知的ObservableCollection当项目发生变化 [英] Notify ObservableCollection when Item changes

查看:1425
本文介绍了通知的ObservableCollection当项目发生变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我这个链接

<一个href=\"http://stackoverflow.com/questions/1427471/c-observablecollection-not-noticing-when-item-in-it-changes-even-with-inotify\">ObservableCollection当它改变项(即使有INotifyPropertyChanged的)

一些技巧来通知的ObservableCollection项目已改变。在这个环节中TrulyObservableCollection似乎正是我要找的。

some techniques to notify a Observablecollection that an item has changed. the TrulyObservableCollection in this link seems to be what i'm looking for.

public class TrulyObservableCollection<T> : ObservableCollection<T>
where T : INotifyPropertyChanged
{
public TrulyObservableCollection()
    : base()
{
    CollectionChanged += new NotifyCollectionChangedEventHandler(TrulyObservableCollection_CollectionChanged);
}

void TrulyObservableCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.NewItems != null)
    {
        foreach (Object item in e.NewItems)
        {
            (item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
        }
    }
    if (e.OldItems != null)
    {
        foreach (Object item in e.OldItems)
        {
            (item as INotifyPropertyChanged).PropertyChanged -= new PropertyChangedEventHandler(item_PropertyChanged);
        }
    }
}

void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    NotifyCollectionChangedEventArgs a = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
    OnCollectionChanged(a);
}

}

但是,当我尝试使用它,我没有得到在集合的通知。我不知道如何正确地实现这在我的C#code:

But when I try to use it, I don't get notifications on the collection. I'm not sure how to correctly implement this in my C# Code:

XAML:

    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding MyItemsSource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
        <DataGrid.Columns>
            <DataGridCheckBoxColumn Binding="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </DataGrid.Columns>
    </DataGrid>

视图模型:

public class MyViewModel : ViewModelBase
{
    private TrulyObservableCollection<MyType> myItemsSource;
    public TrulyObservableCollection<MyType> MyItemsSource
    {
        get { return myItemsSource; }
        set 
        { 
            myItemsSource = value; 
            // Code to trig on item change...
            RaisePropertyChangedEvent("MyItemsSource");
        }
    }

    public MyViewModel()
    {
        MyItemsSource = new TrulyObservableCollection<MyType>()
        { 
            new MyType() { MyProperty = false },
            new MyType() { MyProperty = true },
            new MyType() { MyProperty = false }
        };
    }
}

public class MyType : ViewModelBase
{
    private bool myProperty;
    public bool MyProperty
    {
        get { return myProperty; }
        set 
        {
            myProperty = value;
            RaisePropertyChangedEvent("MyProperty");
        }
    }
}

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChangedEvent(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
            PropertyChanged(this, e);
        }
    }
}

当我运行该程序,我有3复选框假,真,假作为财产的初始化。
但是,当我改变ckeckbox的一个状态,该程序通过item_PropertyChanged但从未在MyItemsSource物业code。

When i run the program, i have the 3 checkbox to false, true, false as in the property initialisation. but when i change the state of one of the ckeckbox, the program go through item_PropertyChanged but never in MyItemsSource Property code.

推荐答案

您已经评价为 // code到trig的有关项目变更现货... 只会触发时集合对象得到改变,当它被设置为一个新的对象,或设置为null,如

The spot you have commented as // Code to trig on item change... will only trigger when the collection object gets changed, such as when it gets set to a new object, or set to null.

使用您的当前实现TrulyObservableCollection的,办理产权变更您的收藏活动,注册的东西 MyItemsSource Col​​lectionChanged 事件C $ C>

With your current implementation of TrulyObservableCollection, to handle the property changed events of your collection, register something to the CollectionChanged event of MyItemsSource

public MyViewModel()
{
    MyItemsSource = new TrulyObservableCollection<MyType>();
    MyItemsSource.CollectionChanged += MyItemsSource_CollectionChanged;

    MyItemsSource.Add(new MyType() { MyProperty = false });
    MyItemsSource.Add(new MyType() { MyProperty = true});
    MyItemsSource.Add(new MyType() { MyProperty = false });
}


void MyItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // Handle here
}

我个人真的不喜欢这种实现。你提出一个 Col​​lectionChanged 事件,说整个集合已被重置,任何时候一个属性更改。当然它会让用户界面随时更新在收集变更的项目,但我看到,是对性能不好,它似乎并不有一种方法来确定哪些属性改变,这是信息的关键件之一我通常需要做的的PropertyChanged 东西的时候。

Personally I really don't like this implementation. You are raising a CollectionChanged event that says the entire collection has been reset, anytime a property changes. Sure it'll make the UI update anytime an item in the collection changes, but I see that being bad on performance, and it doesn't seem to have a way to identify what property changed, which is one of the key pieces of information I usually need when doing something on PropertyChanged.

使用普通的的ObservableCollection ,只是挂钩的的PropertyChanged 事件给它<的项目我preFER code> Col​​lectionChanged 。提供您的UI正确绑定到项目的ObservableCollection ,你不应该需要告诉UI更新时在收集变化的项目的属性。

I prefer using a regular ObservableCollection and just hooking up the PropertyChanged events to it's items on CollectionChanged. Providing your UI is bound correctly to the items in the ObservableCollection, you shouldn't need to tell the UI to update when a property on an item in the collection changes.

public MyViewModel()
{
    MyItemsSource = new ObservableCollection<MyType>();
    MyItemsSource.CollectionChanged += MyItemsSource_CollectionChanged;

    MyItemsSource.Add(new MyType() { MyProperty = false });
    MyItemsSource.Add(new MyType() { MyProperty = true});
    MyItemsSource.Add(new MyType() { MyProperty = false });
}

void MyItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.NewItems != null)
        foreach(MyType item in e.NewItems)
            item.PropertyChanged += MyType_PropertyChanged;

    if (e.OldItems != null)
        foreach(MyType item in e.OldItems)
            item.PropertyChanged -= MyType_PropertyChanged;
}

void MyType_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "MyProperty")
        DoWork();
}

这篇关于通知的ObservableCollection当项目发生变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆