Vaccano
Vaccano

Reputation: 82341

WPF Collections and Databinding

I am new to WPF and trying to wrap my head around WPF's framework, what it does and does not do for you.

To clarify this, I would like to know what is the difference between this:

public List<MyCustomObject> MyCustomObjects
{
    get { return (List<MyCustomObject>)GetValue(MyCustomObjectsProperty); }
    set { SetValue(MyCustomObjectsProperty, value); }
}

public static readonly DependencyProperty MyCustomObjectsProperty =
    DependencyProperty.Register("MyCustomObjects", typeof(List<MyCustomObject>),
    typeof(Main), new UIPropertyMetadata(new List<MyCustomObject>()));



and this:

public ObservableCollection<MyCustomObject> MyCustomObjects { get; set; }

public Main ()
{
    MyCustomObjects = new ObservableCollection<<MyCustomObject>();
}

Upvotes: 2

Views: 3074

Answers (4)

Reed Copsey
Reed Copsey

Reputation: 564413

In the first case, you're setting up a Dependency Property containing a List<T> instance.

In the second, you're making a normal CLR property, but having it setup as an ObservableCollection<T>.

For WPF Data Binding, there are some differences here.

Typically, you want all of your properties in the DataContext (which is the object that, by default, things "bind" to) to either implement INotifyPropertyChanged or to be a Dependency Property. This lets the binding framework know when changes are made to that object. Normally, though, you'd only use a Dependency Property if your working with a custom control - it's usually a better idea to have your object to which your data bound be a separate class, assigned to the DataContext. (For details here, see Josh Smith on MVVM or my recent detailed post on MVVM...)

However, with a collection, you typically also want the binding system to know when the items within the collection change (ie: an item is added). ObservableCollection<T> handles this by implementing INotifyCollectionChanged.

By using the second approach (using an ObservableCollection<T>), your UI can tell when items were added or removed from the collection - not just when a new collection is assigned. This lets things work automatically, like a ListBox adding elements when a new item is added to your collection.

Upvotes: 2

cwap
cwap

Reputation: 11287

1:

You're using a dependency property to "tell" the framework when that property is changed. This will have the following consequences for your binding:

MyCustomObjects.Add(new MyCustomObject()); //Wont update the view through databinding
MyCustomObjects = new List<MyCustomObject>(); //Will update the view through databinding

You could gain the same databinding functionality by implementing INotifyPropertyChanged on which ever class exposes the property, but dependency properties a capable of much more than just notifying about changes. These are rather advanced features though, which you aren't likely to come across in your average joe app :)

2:

You're using an observable collection, which implements INotifyCollectionChanged for you, to tell the databinding whenever the content of the collection has changed. This will have the opposite consequences than #1:

MyCustomObjects.Add(new MyCustomObject()); //Will update the view through databinding
MyCustomObjects = new ObservableCollection<MyCustomObject>(); //Won't update the view through databinding

Upvotes: 1

Thomas Levesque
Thomas Levesque

Reputation: 292425

In addition to Aviad and Reed's answers, I would like to point out a serious bug in your first code sample :

public static readonly DependencyProperty MyCustomObjectsProperty =
    DependencyProperty.Register("MyCustomObjects", typeof(List<MyCustomObject>),
    typeof(Main), new UIPropertyMetadata(new List<MyCustomObject>()));

The new List<MyCustomObject>() used as the default value will be created only once, so by default all instances of your type will share the same List<MyCustomObject> instance, which is probably not what you want... The only sensible default value here is null

Upvotes: 4

Aviad P.
Aviad P.

Reputation: 32639

Ok, we must put some order into things, there's a few concepts mixed in together here.

First of all, you're asking what the difference is between a field-backed property and a dependency property. Google would be your best friend, however I recommend this blog post by WPF's vanguard Josh Smith: Overview of dependency properties in WPF

In short: dependency properties support the richness that is WPF: Styling, animation, binding, metadata, and more.

Secondly, you're asking what the difference is between a List and an ObservableCollection. Well the latter provides change notifications (in the forms of events) on any change to the collection (addition, removal, change of order, clearing, etc.), and the former does not. You can read more about that here: The ObservableCollection Class

In short: ObservableCollection provides change notifications which are required for the UI to automatically reflect changes in the view model.

Upvotes: 4

Related Questions