为什么ObservableCollection没有更新项目更改?

时间:2022-09-12 08:39:34

I noticed that ObservableCollection in WPF reflects changes in GUI only by adding or removing an item in the list, but not by editing it.

我注意到WPF中的ObservableCollection仅通过添加或删除列表中的项目来反映GUI中的更改,而不是通过编辑它。

That means that I have to write my custom class MyObservableCollection instead. What is the reason for this behaviour?

这意味着我必须编写自定义类MyObservableCollection。这种行为的原因是什么?

Thanks

谢谢

5 个解决方案

#1


11  

The ObservableCollection has no way of knowing if you make changes to the objects it contains - if you want to be notified when those objects change then you have to make those objects observable as well (for example by having those objects implement INotifyPropertyChanged)

ObservableCollection无法知道您是否对其包含的对象进行更改 - 如果您希望在这些对象发生更改时得到通知,那么您也必须使这些对象可观察(例如,让这些对象实现INotifyPropertyChanged)

#2


1  

another way of achieving this would be that you implement a new XXXViewModel class that derives from DependencyObject and you put this one in the ObservableCollection.

实现这一目标的另一种方法是你实现一个派生自DependencyObject的新的XXXViewModel类,并将它放在ObservableCollection中。

for this look at this very good MVVM introduction: http://blog.lab49.com/archives/2650

看看这个非常好的MVVM介绍:http://blog.lab49.com/archives/2650

an example for such a class would be:

这样一个类的一个例子是:

public class EntryViewModel : DependencyObject
{
    private Entry _entry;
    public EntryViewModel(Entry e)
    {
        _entry = e;
        SetProperties(e);
    }

    private void SetProperties(Entry value)
    {

        this.Id = value.Id;
        this.Title = value.Title;
        this.CreationTimestamp = value.CreationTimestamp;
        this.LastUpdateTimestamp = value.LastUpdateTimestamp;
        this.Flag = value.Flag;
        this.Body = value.Body;
    }


    public Entry Entry
    {
        get {
            SyncBackProperties();
            return this._entry;
        }
    }


    public Int64 Id
    {
        get { return (Int64)GetValue(IdProperty); }
        set { SetValue(IdProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Id.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IdProperty =
        DependencyProperty.Register("Id", typeof(Int64), typeof(EntryViewModel), new UIPropertyMetadata(new Int64()));

}}

important things here: - it derives from DependencyObject - it operates with DependencyProperties to support WPFs databinding

这里重要的事情: - 它派生自DependencyObject - 它与DependencyProperties一起运行以支持WPF数据绑定

br sargola

br sargola

#3


1  

You can register a method in the view model class aginst the PropertyChanged event of data class objects and listen to them in View model when any change in the property of the data objects happen. This is very easy and straight way to have the control in View model when the items of an observable collection changes. Hope this helps...

您可以在视图模型类中注册数据类对象的PropertyChanged事件中的方法,并在数据对象的属性发生任何更改时在View模型中侦听它们。当可观察集合的项目发生更改时,这是在View模型中拥有控件的非常简单直接的方法。希望这可以帮助...

#4


0  

Probably because items have no way to alert the collection when they are edited - i.e. they might not be observable. Other classes would have similar behavior - no way to alert you to a every change in the graph of referenced classes.

可能是因为项目在编辑时无法提醒集合 - 即它们可能无法被观察到。其他类也会有类似的行为 - 无法提醒您引用类的图形中的每个更改。

#5


0  

As a work-around, you could extract the object from the collection and then reinsert it after you are done processing. Depending on your requirements and concurrency model, this could just make the program ugly, though. This is a quick hack, and not suitable for anything that requires quality.

作为解决方法,您可以从集合中提取对象,然后在完成处理后重新插入它。根据您的要求和并发模型,这可能只会让程序变得丑陋。这是一个快速入侵,并不适合任何需要质量的东西。

Instead, you could implement the collection with an update method that specifically triggers the ContentChanged (not sure about the name) event. It's not pretty, but it is at least quite easy to deal with.

相反,您可以使用专门触发ContentChanged(不确定名称)事件的更新方法来实现集合。它不漂亮,但它至少很容易处理。

Ideally, as kragen2uk says, it would be best to make the objects observable and keep your client code clean and simple.

理想情况下,正如kragen2uk所说,最好使对象可观察并保持客户端代码干净简单。

see also this question.

另见这个问题。

#1


11  

The ObservableCollection has no way of knowing if you make changes to the objects it contains - if you want to be notified when those objects change then you have to make those objects observable as well (for example by having those objects implement INotifyPropertyChanged)

ObservableCollection无法知道您是否对其包含的对象进行更改 - 如果您希望在这些对象发生更改时得到通知,那么您也必须使这些对象可观察(例如,让这些对象实现INotifyPropertyChanged)

#2


1  

another way of achieving this would be that you implement a new XXXViewModel class that derives from DependencyObject and you put this one in the ObservableCollection.

实现这一目标的另一种方法是你实现一个派生自DependencyObject的新的XXXViewModel类,并将它放在ObservableCollection中。

for this look at this very good MVVM introduction: http://blog.lab49.com/archives/2650

看看这个非常好的MVVM介绍:http://blog.lab49.com/archives/2650

an example for such a class would be:

这样一个类的一个例子是:

public class EntryViewModel : DependencyObject
{
    private Entry _entry;
    public EntryViewModel(Entry e)
    {
        _entry = e;
        SetProperties(e);
    }

    private void SetProperties(Entry value)
    {

        this.Id = value.Id;
        this.Title = value.Title;
        this.CreationTimestamp = value.CreationTimestamp;
        this.LastUpdateTimestamp = value.LastUpdateTimestamp;
        this.Flag = value.Flag;
        this.Body = value.Body;
    }


    public Entry Entry
    {
        get {
            SyncBackProperties();
            return this._entry;
        }
    }


    public Int64 Id
    {
        get { return (Int64)GetValue(IdProperty); }
        set { SetValue(IdProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Id.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IdProperty =
        DependencyProperty.Register("Id", typeof(Int64), typeof(EntryViewModel), new UIPropertyMetadata(new Int64()));

}}

important things here: - it derives from DependencyObject - it operates with DependencyProperties to support WPFs databinding

这里重要的事情: - 它派生自DependencyObject - 它与DependencyProperties一起运行以支持WPF数据绑定

br sargola

br sargola

#3


1  

You can register a method in the view model class aginst the PropertyChanged event of data class objects and listen to them in View model when any change in the property of the data objects happen. This is very easy and straight way to have the control in View model when the items of an observable collection changes. Hope this helps...

您可以在视图模型类中注册数据类对象的PropertyChanged事件中的方法,并在数据对象的属性发生任何更改时在View模型中侦听它们。当可观察集合的项目发生更改时,这是在View模型中拥有控件的非常简单直接的方法。希望这可以帮助...

#4


0  

Probably because items have no way to alert the collection when they are edited - i.e. they might not be observable. Other classes would have similar behavior - no way to alert you to a every change in the graph of referenced classes.

可能是因为项目在编辑时无法提醒集合 - 即它们可能无法被观察到。其他类也会有类似的行为 - 无法提醒您引用类的图形中的每个更改。

#5


0  

As a work-around, you could extract the object from the collection and then reinsert it after you are done processing. Depending on your requirements and concurrency model, this could just make the program ugly, though. This is a quick hack, and not suitable for anything that requires quality.

作为解决方法,您可以从集合中提取对象,然后在完成处理后重新插入它。根据您的要求和并发模型,这可能只会让程序变得丑陋。这是一个快速入侵,并不适合任何需要质量的东西。

Instead, you could implement the collection with an update method that specifically triggers the ContentChanged (not sure about the name) event. It's not pretty, but it is at least quite easy to deal with.

相反,您可以使用专门触发ContentChanged(不确定名称)事件的更新方法来实现集合。它不漂亮,但它至少很容易处理。

Ideally, as kragen2uk says, it would be best to make the objects observable and keep your client code clean and simple.

理想情况下,正如kragen2uk所说,最好使对象可观察并保持客户端代码干净简单。

see also this question.

另见这个问题。