Monday, May 30, 2011

How to customize an ItemsControl

Introduction
If you are a Silverlight developer there will be a moment when you’ll look at a ListBox and not be happy with its default behavior. You are not exactly a beginner – you know how to style and retemplatize controls and even how to write your own custom controls – in fact you did that quite a few times. Depending on what changes are needed you’ll consider different solutions. Modifying the style and template of the ListBox comes to mind but it is not very clear how to achieve some of the customizations even if you are willing to modify the template of the ListBox. If the changes you need are substantial you may be willing to write a custom control but in the case of a ListBox this appears to be more difficult than expected. A ListBox is not just a simple control. It is a container that manages a collection. And it is more than a container in the sense that a Grid or a Canvas are containers. A ListBox has an ItemsSource that can be bound to a data source. Writing a custom ListBox is quite different than writing a custom Panel.

 If you recognize yourself in this, then this article is for you.
You will see that in most cases customizing a list is not that hard. A couple of things are worth mentioning from start. First, there are plenty of ways you can customize a ListBox without needing to write a custom control. Second, the main character in this story is the class ItemsControl and not ListBox. You may be more familiar with the ListBox but most of the concepts we are going to analyze belong to the ItemsControl. If you get to write a custom list it is much more likely that you’ll inherit your class from ItemsControl rather than from ListBox.
The examples discussed in this article are illustrated in a sample Silverlight application you can view at http://www.ladimolnar.com/Projects/ItemsControlDemo. You can download the code from http://www.ladimolnar.com/Sources/ItemsControlDemo.zip.


When you don’t need to customize anything at all
We’ll start with a very simple case but one that surprisingly gives headaches to a lot of people. Let’s suppose you need to show a ListBox that does not have any mouse over or selection effect. Actually your list does not even have the concept of “selected”. It seems that the otherwise useful features of the regular ListBox are just getting in your way.
The solution to this problem is very simple. All you have to do is to replace the ListBox with the ItemsControl. The ListBox itself is an ItemsControl with additional features that in this case you don’t need. As you see in Figure 1, the ItemsSource will allow you to bind to the data and the ItemTemplate will allow you to specify the visuals in the same way they do for a ListBox.
<ItemsControl
    ItemsSource="{Binding ProductList}"
    ItemTemplate="{StaticResource ProductItemTemplate}" />
Figure 1
The inner workings of an ItemsControl
Before we go any further, it will be useful to talk a little bit about how the ItemsControl class works. When things will be simpler to illustrate with a ListBox I will refer to it as well but all the fundamental concepts discussed here apply to both. Remember that ListBox inherits from ItemsControl.

Read more: LadiMolnar.com