In my previous post (MultiBinding and Command Parameters in WPF), I discussed how you can pass multiple values into a CommandParameter. In this post, In this post, we will make sure the User Interface get's updated when the Collection changes (items are added or removed), and will need MultiBindings to keep the View Model clean. If you haven't yet implement INotifyPropertyChanged on your entities, see my previous post on INotifyPropertyChanged and WPF.

We want our ComboBox (or any list control, for that matter) to accurately display the list of items in the collection when said collections change. We get this functionality by implementing INotifyCollectionChanged (we get this out of the box with the ObservableCollection collection class, but we are going to implement it by hand first). But before we jump into coding, lets create the framework and the failing test (albeit a UI test).

To do this, we are going to start with the Add Product functionality. This will build on the previous MultiBinding from the Update Price command, and leverage the same Parameter and MultiValueConverter classes. We first refactor the XAML to move the resource definition to the Window as shown here:

We also need to refactor the ChangeNotificationParameter class to include another property for the List itself. I chose to add another property instead of create a new parameter class since we will be needing all of the fields for the Delete implementation. The new code is shown here:

publicclass ChangeNotificationParameter

{

public ContentControl CallBackControl { get; set; }

public Product Prod { get; set; }

public IList<Product> Products { get; set; }

}

The last refactoring we need to conduct is in the MultiValueConverter itself to take advantage of the new property.

The XAML for the new button (placed in the StackPanel with the Update Price button) looks like this (passing in the Products List from the View Model and the Label from the Window):

When we run the app, we see that we have two items in the ComboBox (our two hardcoded products). Clicking the Add Product button adds a product (confirmed by the label), but our ComboBox still shows only two items.

To enable the hook up of the notifications, we need to create a custom class that implements INotifyPropertyChanged. We also want to keep our list as an IList<Product> (our current implementation).

I first create an interface with both interfaces included. In this manner, I can still code to an interface instead of concrete classes.

Now for the class itself. I chose to use the Decorator pattern, since it provided the least friction. There is still a bit of code to write, but less than other options I considered. The entire class is shown here:

For each of the methods that alter the collection, we need to raise the CollectionChanged event. This event has a custom Event Arguments class that takes in its constructor an enumeration of the change that took place (Add, Move, Replace, Reset, or Remove). (One could argue whether it makes sense to make specific action calls or always declare the action as Reset, but that isn't the purpose of this post.)

The ViewModel needs to be changed to utilize the new collection class. The altered code is shown here:

public ChangeNotificationViewModel()

{

Products = new ProductList(new ProductService().GetProducts());

}

public ChangeNotificationViewModel(IList<Product> products)

{

Products = new ProductList(products);

}

public IProductList Products { get; set; }

Now when you click to Add Product, the list automatically shows the new product.

Now, to do it the easy way! Change the ViewModel code to use an Observable Collection, and you can eliminate the entire custom class!