Overview
WPF provides a number of conveniences in terms of accessing and binding external data sources. This tutorial shows how you can bind and display XML data using a data template in XAML. This technique is also known as creating an XML data island.
XML Data Binding
For this example we will create a very simple XAML application that displays a list of favorites (URLs) from an XML data source. In our XAML document we will define a data source as a resource and supply that resource with our XML data, in this case a list of URLs. To do this we will use the XMLDataProvider tag.
<!-- define the XML data source as a resource -->
<XmlDataProvider x:Key="BookmarkData" XPath="/Favorites">
<x:XData>
<Favorites xmlns="">
<Bookmark>
<Title>Google</Title>
<URL>http://www.google.com</URL>
</Bookmark>
<Bookmark>
<Title>Amazon</Title>
<URL>http://www.amazon.com</URL>
</Bookmark>
<Bookmark>
<Title>Slashdot</Title>
<URL>http://www.slashdot.com</URL>
</Bookmark>
<Bookmark>
<Title>Ars Technica</Title>
<URL>http://www.arstechnica.com</URL>
</Bookmark>
<Bookmark>
<Title>New Egg</Title>
<URL>http://www.newegg.com</URL>
</Bookmark>
</Favorites>
</x:XData>
</XmlDataProvider>
As you can see, we have also defined an XPath attribute within the XMLDataProvider tag. This path definition allows us to access the XML data based on the parent node "Favorites". Once this has been defined, we need to prepare our bookmark data for display by binding it to a data template. We can do this using the DataTemplate and Binding tags, also within the resources portion of our XAML document.
<!-- create a data template to display the desired XML node values -->
<DataTemplate x:Key="BookmarkDataTemplate">
<StackPanel Margin="5">
<TextBlock FontSize="12" FontWeight="Bold" Foreground="White">
<TextBlock.Text>
<Binding XPath="Title"/>
</TextBlock.Text>
</TextBlock>
<TextBlock FontSize="10" Foreground="LightGray">
<TextBlock.Text>
<Binding XPath="URL"/>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</DataTemplate>
A data template is now configured to accept both Title and URL node values, displaying each in its own TextBlock. For purposes of layout, we have arranged these in a single StackPanel. The Binding tag and XPath attribute have been used to define the specific XML nodes we are interested in pulling data from.
All that is left is to use the data template to actually write our data to the screen. We do this by referencing the data template in the main portion of our XAML document. Here we will bind the data to a standard ListBox control using the ItemsSource and ItemTemplate properties.
<!-- write the data to the screen by binding the data template to a list box -->
<StackPanel>
<TextBlock FontSize="14" FontWeight="Bold" Margin="10">My Favorites</TextBlock>
<ListBox
Background="#999"
BorderThickness="2"
BorderBrush="White"
Margin="10"
ItemsSource="{Binding Source={StaticResource BookmarkData}, XPath=Bookmark}"
ItemTemplate="{StaticResource BookmarkDataTemplate}"/>
</StackPanel>
The ItemsSource property specifies a binding source referencing the original XML data we defined in the resources portion of our document. The XPath property is set to "Bookmark", the repeating child node within "Favorites". Lastly, the value for ItemTemplate is set to refer to the key of our data template, "BookmarkDataTemplate".
Displayed in its entirity, our XAML file now looks like the following:
<Window x:Class="WindowsApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowsApplication1" Width="550" Height="400" Name="Form1">
<Window.Resources>
<XmlDataProvider x:Key="BookmarkData" XPath="/Favorites">
<x:XData>
<Favorites xmlns="">
<Bookmark>
<Title>Google</Title>
<URL>http://www.google.com</URL>
</Bookmark>
<Bookmark>
<Title>Amazon</Title>
<URL>http://www.amazon.com</URL>
</Bookmark>
<Bookmark>
<Title>Slashdot</Title>
<URL>http://www.slashdot.com</URL>
</Bookmark>
<Bookmark>
<Title>Ars Technica</Title>
<URL>http://www.arstechnica.com</URL>
</Bookmark>
<Bookmark>
<Title>New Egg</Title>
<URL>http://www.newegg.com</URL>
</Bookmark>
</Favorites>
</x:XData>
</XmlDataProvider>
<!-- create a data template to display the desired XML node values -->
<DataTemplate x:Key="BookmarkDataTemplate">
<StackPanel Margin="5">
<TextBlock FontSize="12" FontWeight="Bold" Foreground="White">
<TextBlock.Text>
<Binding XPath="Title"/>
</TextBlock.Text>
</TextBlock>
<TextBlock FontSize="10" Foreground="LightGray">
<TextBlock.Text>
<Binding XPath="URL"/>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</DataTemplate>
</Window.Resources>
<!-- write the data to the screen by binding the data template to a list box -->
<StackPanel>
<TextBlock FontSize="14" FontWeight="Bold" Margin="10">My Favorites</TextBlock>
<ListBox
Background="#999"
BorderThickness="2"
BorderBrush="White"
Margin="10"
ItemsSource="{Binding Source={StaticResource BookmarkData}, XPath=Bookmark}"
ItemTemplate="{StaticResource BookmarkDataTemplate}"/>
</StackPanel>
</Window>
When compiled, a window is displayed with a standard ListBox populated with our XML data: