0

When I'm binding, say a Label to a string, I define the string this way:

private string _lbl;
public string Lbl
    {
     get
     {
          return = _lbl;
     }
      set
     {
         _lbl=value;
          OnPropertyChanged("Lbl");
     }
}

With the INotifyPropertyChanged interface implemented in my class.

Should I define the same way an ObservableCollection or I just could leave it this way?

public ObservableCollection<File> myFiles {get; set;}

Sturm
  • 3,968
  • 10
  • 48
  • 78

2 Answers2

5

As a general rule, I tend to define ObservableCollections like this:

    private ObservableCollection<Item> _items;
    public ObservableCollection<Item> Items
    {
        get { return _items ?? (_items = new ObservableCollection<Item>()); }
    }

This is called "Lazy initialization", where the ObservableCollection is only instantiated where it is first accessed.

This is a good way to ensure your Collection Will Never Be Null

Notice that it does not have a setter, because an ObservableCollection is not something that you usually assign to. Instead, if you want to completely replace items, do:

Items.Clear();
//... Add all the new items

This avoids WPF having to rebind all the CollectionChanged events and stuff in order to listen to and react to items added / removed from the collection. You only have 1 instance of the collection, forever. Whatever items you place on it, the collection remains the same.

This is not to be confused with the PropertyChange notification inside the ITEMS of the collection. WPF handles these concepts separately, because property changes are notified by ITEMS, but Collection changes (Item added or removed) are notified by the Collection itself.

Community
  • 1
  • 1
Federico Berasategui
  • 43,562
  • 11
  • 100
  • 154
  • Thanks for the answer, but the last sentences confuses me a little bit. If I add an item to a ObservableCollection defined like that, every element that I've bound to that collection will automatically update? (I guess so, but just for be sure..) – Sturm Jun 06 '13 at 22:05
  • @Sturm no. You're confusing `CollectionChanged` with `PropertyChanged`, which are 2 different concepts. See my Edit – Federico Berasategui Jun 06 '13 at 22:06
  • 1
    Isn't Items a property? It's defined as a property, I believe. – Sturm Jun 06 '13 at 22:07
  • 1
    @sturm It's a property. But it's a read only property that never changes and therefore does not need Change Notification. – Federico Berasategui Jun 06 '13 at 22:08
  • 1
    Then Items.Add(myItem); is not considered as changing the Items property but a CollectionChanged? – Sturm Jun 06 '13 at 22:11
  • 1
    @Sturm exactly. You're not changing the "Items" property in itself, you are adding an item to the collection, and the collection raises the `CollectionChanged` event. – Federico Berasategui Jun 06 '13 at 22:14
1

If the myFiles property can change, then yes, you should raise the PropertyChanged event. If not (that is, if it's got no setter, or it has a private setter that is only set once, e.g. in the constructor), then you don't need to raise the event. The collection itself will raise its own PropertyChanged and CollectionChanged events, but the object that contains the collection must raise PropertyChanged if the property that contains the collection changes.

Michael Gunter
  • 12,528
  • 1
  • 24
  • 58
  • Where's the hole? There are valid use cases for ObservableCollection properties changing outright. – Michael Gunter Jun 06 '13 at 21:59
  • Ah. The no-setter scenario. Edited. – Michael Gunter Jun 06 '13 at 22:00
  • removed the downvote. Still, my solution is better performance-wise. – Federico Berasategui Jun 06 '13 at 22:05
  • Not so. If the Items property is always used, and it is used more than once, then your lazy-initialization hurts performance. It's all about use cases. – Michael Gunter Jun 06 '13 at 22:06
  • `If the Items property is always used, and it is used more than once, then your lazy-initialization hurts performance.` - Can you explain that? I think you did not understand what my code does. It's only intantiating the collection once at first access. Regardless of the usage. – Federico Berasategui Jun 06 '13 at 22:35
  • It's instantiating the collection on first access, but it's checking the value of _items for null on every access. That null check is a performance hit, however small. That's the trade-off with lazy initialization. – Michael Gunter Jun 07 '13 at 14:40