views:

509

answers:

4

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.

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

Thanks

+5  A: 

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)

Kragen
OK then. I implement INotifyPorpertyChanged interface. Thanks
PaN1C_Showt1Me
A: 

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.

Richard Watson
A: 

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.

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

see also this question.

IanGilham
Extracting and reinserting is a really nice hack :) Now I know that I have to forget about this trick :)
PaN1C_Showt1Me
A: 

hi,

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.

for this look at this very good MVVM introduction: 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

br sargola

Sargola
Looks interesting, but I don't understand for what purpose do you inherit from DependencyObject ? dependency properties bound to WPF inside the class should be enough.. or ?
PaN1C_Showt1Me
@PaN1C_Showt1Me: GetValue/SetValue are implemented there. br Sargola
Sargola
@Sargola: Ah ok.. The UserControl is a DependencyObject too.. didn't notice that. Thanks
PaN1C_Showt1Me