Binding a ListBox's ItemsSource to a List(Of String) won't visually update the ListBox after an .Add() even if NotifyPropertyChanged is used. I fixed this by using an ObservableCollection(Of String) instead of a List(Of String). ObservableCollection works because it implements INotifyPropertyChanged and INotifyCollectionChanged. Therefore NotifyPropertyChanged isn't needed with ObservableCollection as notification is internal. Do I have this right?

I'm a bit bothered by the lack of symmetry. Is there a collection that implements INotifyPropertyChanged but not INotifyCollectionChanged? My idea is to always use NotifyPropertyChanged for symmetry.

I'm also wondering if I am missing something. Is it possible to use List(Of String) but in some other way that will cause the UI to update?

asked 02 Sep '10, 13:04

BSalita's gravatar image

BSalita
276131417
accept rate: 22%


That's a very general MVVM question, but I think I can give you a specific answer. INotifyPropertyChanged and INotifyCollectionChanged handle two very different cases. Consider this:

#region " MyProperty "
public IEnumerable<string> MyProperty
{
    get
    {
        return m_MyProperty;
    }
    set
    {
        if (value == null)
        {
            throw new ArgumentNullException(m_MyPropertyName);
        }
        if (m_MyProperty != value)
        {
            m_MyProperty = value;
            NotifyPropertyChanged(m_MyPropertyArgs);
        }
    }
}
private IEnumerable<string> m_MyProperty = null;
private static readonly PropertyChangedEventArgs m_MyPropertyArgs =
    NotifyPropertyChangedHelper.CreateArgs<MyClass>(o => o.MyProperty);
private static string m_MyPropertyName =
    NotifyPropertyChangedHelper.GetPropertyName<MyClass>(o => o.MyProperty);
#endregion

Now let's say I bind an ItemsControl's ItemsSource property to MyProperty. Both of these statements will notify the View of a change, because I've implemented INotifyPropertyChanged:

var col1 = new Collection<string>();
col1.Add("test");
MyProperty = col1;

var col2 = new ObservableCollection<string>();
col2.Add("test");
MyProperty = col2;

However, this does not notify the View:

col1.Add("test2");

But this does notify it:

col2.Add("test2");

So there are two scenarios: overwriting the property with an entirely new collection, or updating the collection without changing the property itself. For the first case, you don't need an ObservableCollection, but for the second, you do.

You'll notice that in SoapBox Core, I don't use ObservableCollection very much, mostly because I've been taking a more functional approach, and updating a collection is just too much "mutation" for me. :)

link

answered 02 Sep '10, 20:30

Scott%20Whitlock's gravatar image

Scott Whitlock ♦♦
696262833
accept rate: 50%

From what I see here, the issue is that NotifyPropertyChanged isn't working at all. ObservableCollection always works. It will take a week to get back on this but I believe there's some anamoly or bug somewere, possibly something subtle in my code.

(03 Sep '10, 16:00) BSalita

@BSalita: watch out for code that sets the property on your View to Nothing. That will actually break the binding, and you'll stop getting updates.

(03 Sep '10, 17:58) Scott Whitlock ♦♦
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "Title")
  • image?![alt text](/path/img.jpg "Title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×1
×1
×1
×1

Asked: 02 Sep '10, 13:04

Seen: 1,321 times

Last updated: 03 Sep '10, 17:58

Related questions

powered by OSQA