Click here to Skip to main content
15,884,050 members
Articles / Desktop Programming / WPF

NotifyParentObservableCollection (Part 1) monitors changes of its children properties

Rate me:
Please Sign up or sign in to vote.
3.50/5 (4 votes)
23 Jan 2011Eclipse3 min read 44.2K   361   8   18
ObservableCollection attaches to the PropertyChanged events of its children and raises the ChildPropertyChanged event accordingly. Very useful when you need to update / select / arrange / move items.

Table of Contents

Introduction

Some of the most common tasks in GUI programming are to select multiple items from the list, to modify properties of multiple items, to rearrange items in the list, or to copy / move items from one list to another.

I assume that you are using WPF and MVVM pattern.

Let's consider the following simple example. You want to switch on / off individual bits of the Hex variable, like this:

binary.JPG

You create properties on your ViewModel holding list(s) or collection(s) of items, and bind them to some ItemsControl(s) on your view. You make an ItemTemplate containing CheckBoxes, and bind them to properties of your items. Now what? How do you implement the needed functionality?

You have a few alternatives:

  • Make view model class(es) for your items and put all the logic there, so every time the Item.IsSelected property is changed, you update the Hex variable. Oops, the Hex variable belongs to the parent VM, so your items will have to have a member variable holding the parent VM or a delegate callback.
  • Make dumb items to hold data, make a bunch of converters, and implement logic in those converters / XAML, like so;
  • XML
    TextBox.Text = "{Binding CheckBox.IsChecked, Converter=....}"

    Of course, you will need a pretty complicated FlagConverter which can combine multiple flag values (I have a bunch of those in my WPF library).

  • Don't re-invent the wheel, and use the utility classes that I created to simplify things. With those utility classes, any task of updating / selecting / arranging / moving items is a snap.

Example

The XAML is simplicity itself:

XML
<ListBox ItemsSource="{Binding Selectors}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding IsSelected}" 
                      Content="{Binding Caption}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

The ViewModel cannot be simpler:

C#
private NotifyParentObservableCollection<LookupItem> _selectors;
public NotifyParentObservableCollection<LookupItem> Selectors
{
    get { return _selectors; }
    private set
    {
        if (_selectors != null)
        {
            _selectors.ChildPropertyChanged -= OnSelectorsChildPropertyChanged;
        }
        _selectors = value;
        if (_selectors != null)
        {
            _selectors.ChildPropertyChanged += OnSelectorsChildPropertyChanged;
        }
        OnPropertyChanged("Selectors");
    }
}

private void OnSelectorsChildPropertyChanged(object sender, 
                                             PropertyChangedEventArgs e)
{
    var item = sender as LookupItem;
    if (e.PropertyName == "IsSelected")
    {
        if (item.IsSelected)
        {
            Hex |= (int) item.Value;
        }
        else
        {
            Hex &= ~(int) item.Value;
        }
    }
}

Selectors = new NotifyParentObservableCollection<LookupItem>
{
    new LookupItem { Value = 1, Caption = "0x00000001" },
    new LookupItem { Value = 2, Caption = "0x00000010" },
    new LookupItem { Value = 4, Caption = "0x00000100" },
    new LookupItem { Value = 8, Caption = "0x00001000" },
};

Voila, we are done with our task. Can you beat the simplicity?

NotifyParentObsevableCollection and LookupItem

C#
public class LookupItem : INotifyPropertyChanged

LookupItem is a utility class used as a generic ViewModel for an item when you need to update / select / arrange / move those items.

LookupItem has a bunch of most useful for those scenarios properties, and it implements the INotifyPropertyChanged interface to notify its parent NotifyParentObservableCollection<T> when any of its properties change. If you need more properties, inherit from it and add whatever you need.

C#
public class NotifyParentObservableCollection<T> : ObservableCollection<T>

NotifyParentObservableCollection<T> attaches to the PropertyChanged events of its children and raises the ChildPropertyChanged event accordingly.

NotifyParentObservableCollection<T> inherits from ObservableCollection<T>, and overrides OnCollectionChanged() and ClearItems() to attach / detach handlers to children.

That's it. Again, can you beat the simplicity?

When I write code, my goal is to eliminate as much lines of code as possible, but no more.

My motto: The less lines of code, the less potential errors.

Caution

Since NotifyParentObservableCollection<T> strongly attaches to the PropertyChanged events of its children, you have to Clear() the collection after you are done using it to eliminate potential memory leaks.

Of course, if the parent collection has the same life span as its children, you can safely ignore this advice, but if children can outlive the collection, don't forget to call Clear().

Revision History

  • January 20, 2011 - Created the article.

License

This article, along with any associated source code and files, is licensed under The Eclipse Public License 1.0


Written By
Software Developer (Senior) Liquidnet
United States United States
Michael is a software developer who still remembers punch cards, computers with 4 Kbytes RAM, and 3270s. His personal computers were Apple IIe, Commodore, and PC XT (with the whole 640 Kbytes RAM and 2 floppy drives!!!). Wow, that was a powerhouse.

Fast forward 32 years through FORTRAN, PL-I, Algol, Pascal, Prolog, LISP, C, Basic, Clipper, Assembly, FoxPro, DHTML, JavaScript, C++, you name it, to C# 4.0.

Of course, real men use machine code to write software, but what a difference a few years make! No more mallocs and callocs, GC magically collects unused objects, dynamic objects magically call IUnknown::QueryInterface, Reflection magically gives you metadata and even generates help files, WPF magically binds stuff together...

Read some of Michael's articles here.

BindingHub (a WPF component and a design pattern) [^].

Notifying parent of changes to children's properties [^].

Point-In-Time database (coming soon)

Composite Menus and other ItemsControls (coming soon)

Adorners framework (coming soon)

Drag-n-drop data transfer framework (coming soon)

Converters and MarkupExtensions (coming soon)

Download complete WPF library [^].

Comments and Discussions

 
QuestionIs it possible to use ObservableCollection<CheckBoxValue> instead ? Pin
John 20138-Dec-13 3:53
John 20138-Dec-13 3:53 
GeneralFreezableCollection Pin
haindl20-Jan-11 23:54
haindl20-Jan-11 23:54 
GeneralMy vote of 1 Pin
SledgeHammer0120-Jan-11 9:57
SledgeHammer0120-Jan-11 9:57 
GeneralRe: My vote of 1 [modified] Pin
Michael Agroskin20-Jan-11 10:21
Michael Agroskin20-Jan-11 10:21 
GeneralRe: My vote of 1 Pin
SledgeHammer0120-Jan-11 12:10
SledgeHammer0120-Jan-11 12:10 
GeneralRe: My vote of 1 Pin
Michael Agroskin20-Jan-11 12:22
Michael Agroskin20-Jan-11 12:22 
GeneralRe: My vote of 1 Pin
SledgeHammer0120-Jan-11 12:46
SledgeHammer0120-Jan-11 12:46 
GeneralRe: My vote of 1 Pin
Michael Agroskin20-Jan-11 13:16
Michael Agroskin20-Jan-11 13:16 
GeneralRe: My vote of 1 Pin
SledgeHammer0120-Jan-11 14:40
SledgeHammer0120-Jan-11 14:40 
GeneralRe: My vote of 1 Pin
Michael Agroskin20-Jan-11 16:22
Michael Agroskin20-Jan-11 16:22 
GeneralRe: My vote of 1 Pin
SledgeHammer0120-Jan-11 16:48
SledgeHammer0120-Jan-11 16:48 
GeneralRe: My vote of 1 Pin
Sacha Barber20-Jan-11 21:53
Sacha Barber20-Jan-11 21:53 
GeneralRe: My vote of 1 [modified] Pin
Michael Agroskin21-Jan-11 11:46
Michael Agroskin21-Jan-11 11:46 
GeneralRe: My vote of 1 Pin
Sacha Barber21-Jan-11 22:16
Sacha Barber21-Jan-11 22:16 
AnswerRe: My vote of 1 Pin
Michael Agroskin23-Jan-11 6:26
Michael Agroskin23-Jan-11 6:26 
GeneralRe: My vote of 1 Pin
SledgeHammer0120-Jan-11 12:50
SledgeHammer0120-Jan-11 12:50 
GeneralRe: My vote of 1 Pin
Michael Agroskin20-Jan-11 13:09
Michael Agroskin20-Jan-11 13:09 
AnswerRe: My vote of 1 Pin
Michael Agroskin23-Jan-11 6:24
Michael Agroskin23-Jan-11 6:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.