WPFwiki, wpf, wiki, .net 3.0, windows presentation foundation, FAQ, free resources, solution, development, microsoft Home of the world's largest WPF FAQ

Q16.1 - Create a collection in XAML

Modified: Tue, 15 Dec 2009 11:00 by alexhaffey - Categorized as: WPF FAQ
Edit

Category

XAML

Edit

Question

How do I declaratively create an object collection in XAML?

Edit

Answer

First, if you want to declare a collection of custom class types, you'll have to create the custom class in code. You cannot define a new class in XAML.

There are four ways to declare a CLR object collection in XAML: x:Array, ArrayList, standard XAML declarations, and the CollectionViewSource class. We'll discuss each one here.

As stated previously, if you want to create a collection of a custom type, you will have to define it beforehand in code. The code snippets of this article assume that the following class is defined:

namespace WindowsApplication1
{
  public class Composer
  {
    public Composer()
    {
    }
    public string Name
    {
      get { return m_name; }
      set { m_name = value; }
    }
    public int Birth
    {
      get { return m_birth; }
      set { m_birth = value; }
    }
    
    private string m_name;
    private int m_birth;
  }
}


x:Array
This class is a markup extension of the XAML namespace that specifically allows the creation of an object list in XAML without having to define a Collection class in code. Note, however, that it is usually wiser to have such a class, particularly if you want a strongly typed collection that supports the INotifyPropertyChanged (to advise the binding of changes in the collection). Typically, that would be an ObservableCollection-derived class.

Using "x:Array" is quite straigthforward. Here's an example:

<Window x:Class="WindowsApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:WindowsApplication1" 
Title="WindowsApplication1"
Height="300"
Width="300"
    >
  <Window.Resources>
    <x:Array x:Key="ComposerList" Type="{x:Type custom:Composer}">
      <custom:Composer Name="Mozart, Wolfgang Amadeus" Birth="1756"/>
      <custom:Composer Name="Górecki, Henryk Mikolaj" Birth="1933"/>
      <custom:Composer Name="Massenet, Jules" Birth="1842"/>
    </x:Array>
    <DataTemplate x:Key="ComposerTemplate">
      <TextBlock Text="{Binding Path=Name}"/>
    </DataTemplate>
  </Window.Resources>
  <StackPanel>
    <ListBox ItemTemplate="{StaticResource ComposerTemplate}">
      <ListBox.ItemsSource>
        <Binding Source="{StaticResource ComposerList}" Path="Items"/>
      </ListBox.ItemsSource>
    </ListBox>
  </StackPanel>
</Window>


ArrayList
The well-known ArrayList CLR class could also be used similarly to x:Array, but it is somewhat less concise to use. First, add the following namespace mapping:

xmlns:coll="clr-namespace:System.Collections;assembly=mscorlib"

Then, we only need to modify the previous snippet slightly:

<coll:ArrayList x:Key="ComposerCollection">
   <custom:Composer Name="Mozart, Wolfgang Amadeus" Birth="1756"/>
   <custom:Composer Name="Górecki, Henryk Mikolaj" Birth="1933"/>
   <custom:Composer Name="Massenet, Jules" Birth="1842"/>
</coll:ArrayList>


And modify the binding:

<Binding Source="{StaticResource ComposerCollection}"/>


Standard XAML
If you have a custom collection definition, you could use it directly in XAML syntax. This produces more readable XAML. Here, a ComposerCollection has been defined in code and is used as follows:

    <custom:ComposerCollection x:Key="ComposerCollection">
      <custom:Composer Name="Mozart, Wolfgang Amadeus" Birth="1756"/>
      <custom:Composer Name="Górecki, Henryk Mikolaj" Birth="1933"/>
      <custom:Composer Name="Massenet, Jules" Birth="1842"/>
    </custom:ComposerCollection>


CollectionViewSource
CollectionViewSource is entirely different. It is not used to create a collection but rather to allow sorting, filtering and grouping on an existing collection. Naturally, this collection can be created in code-behind or can use an x:Array as demonstrated above.

To have a collection view sorted by composer name using the same code as the "x:Array" example, we only have to do the following:

- Add the following reference


xmlns:compModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"

- Add the following resource

    <CollectionViewSource Source="{Binding Source={StaticResource ComposerList}, Path=Items}"
                          x:Key="ComposerViewSource">
      <CollectionViewSource.SortDescriptions>
        <compModel:SortDescription PropertyName="Name"/>
      </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>


- Modify the Binding of the ListBox

<Binding Source="{StaticResource ComposerViewSource}"/>


Of course, you are not limited to "x:Array" and can create a CollectionViewSource based on a list created by any of the three previously presented methods.

Geometry Homework

All content is Copyright ©2007 Xceed Software Inc. unless otherwise indicated. See the Terms of Service. Contributors must read and agree to the Contribution Policy. WPFwiki is brought to you by Xceed, makers of the powerful yet free Xceed DataGrid for WPF.