Thursday 13 September 2012

The WPF DataGrid - Explained

It might seem mysterious how one can populate a WPF DataGrid from System.Windows.Controls, the "Fourth" Incarnation of the DataGrid.

Answer: Create your own ObservableCollection

All lies in setting the ItemsSource property to an ObservableCollection of custom-built ViewModel objects. As we know from MVVM design, the ViewModel is just like a "screen" on top of the Model that keeps the Model up to date and is also responsible for notifications when properties change, to the relevant observers.

From ObservableCollection to NotifiableCollection

ObservableCollection is good for dealing with "macro" changes to the Collection (as when an Item gets added or deleted) but is not good at detecting and propagating changes when properties on individual items change. For that, a custom-built NotifiableCollection is appropriate (see this discussion on forums.silverlight.net (general principle applies to WPF also)) and also this blog post from a software consulting firm specialising in "nearshoring").

Declaring the NotifiableCollection has to be done in "Generic" Style

public class NotifiableCollection<T>: ObservableCollection<T> where T: class, INotifyPropertyChanged {... }

Note that you also need to declare an EventHandler within the Collection definition, which can be simply done: public event EventHandler<MyEventArgsClass> InterestingPropertiesChanged, or some such similar declaration. Conceptually, this is like defining a multicast delegate to hold the function pointers representing methods to be invoked when an "interesting" property is changed.

Conclusions

The main conclusion is this.

It's nice to know what you can do in WPF using System.Windows.Controls. But a knowledge of controls alone is no use without working knowledge of the relevant object model and component model namespaces.

Thes are System.ComponentModel (INotifyPropertyChanged) and System.Collections.ObjectModel (ObservableCollection). Understand the ComponentModel and Collections Object Model in detail.

No comments: