Binding to XML

The purpose of this tutorial is to show you how to bind a RadComboBox control to a data defined in a XML file. In a few words, the operations you need to perform are to convert the XML to a collection of business objects and then bind that collection using the ItemsSource property of the RadComboBox.

The final result should look like the snapshot below:

Silverlight RadComboBox Bound to XML Data

The next code snippet shows the XML declaration, used in this tutorial:

<?xml version="1.0" encoding="utf-8" ?> 
<Items> 
    <XmlNodeItem Team="Barcelona" Country="Spain"/> 
    <XmlNodeItem Team="Juventus" Country="Italy"/> 
    <XmlNodeItem Team="Inter" Country="Italy"/> 
    <XmlNodeItem Team="Ac Milan" Country="Italy"/> 
    <XmlNodeItem Team="Real M" Country="Spain"/> 
    <XmlNodeItem Team="Arsenal" Country="England"/> 
    <XmlNodeItem Team="Manchester U" Country="England"/> 
    <XmlNodeItem Team="Bayern" Country="Germany"/> 
    <XmlNodeItem Team="Porto" Country="Portugal"/> 
    <XmlNodeItem Team="Liverpool" Country="England"/> 
    <XmlNodeItem Team="Ajax" Country="Holland"/> 
    <XmlNodeItem Team="Olimpic M" Country="France"/> 
</Items> 
  • Add a new RadComboBox declaration in your XAML.

<telerik:RadComboBox x:Name="radComboBox" Width="200"/> 
  • Create a new class named XmlNodeItem. This class is pretty simple and it represents a separate node from the XML document. Its properties are Team and Country. Both of the properties are of type string. Here is the source code:

public class XmlNodeItem 
{ 
    [XmlAttribute( AttributeName = "Team" )] 
    public string Team 
    { 
        get; 
        set; 
    } 
 
    [XmlAttribute( AttributeName = "Country" )] 
    public string Country 
    { 
        get; 
        set; 
    } 
} 
Public Class XmlNodeItem 
Private _Team As String 
    <XmlAttribute(AttributeName = "Team")> _ 
    Public Property Team() As String 
        Get 
            Return _Team 
        End Get 
        Set(ByVal value As String) 
            _Team = value 
        End Set 
        End Property 
 
        Private _Country As String 
        <XmlAttribute(AttributeName = "Country")> _ 
        Public Property Country() As String 
            Get 
                Return _Country 
            End Get 
            Set(ByVal value As String) 
                _Country = value 
            End Set 
        End Property 
    End Class 
  • Create a new class named XmlNodeItemList, which derives from ObservableCollection of XmlNodeItem. This is a collection that will be created from the XML file. The RadComboBox will be bound to this collection.

[XmlRoot( ElementName = "Items" )] 
public class XmlNodeItemList : ObservableCollection<XmlNodeItem> 
{ 
    public void AddRange( IEnumerable<XmlNodeItem> range ) 
    { 
        foreach ( XmlNodeItem node in range ) 
        { 
            this.Add( node ); 
        } 
    } 
} 
    <XmlRoot(ElementName = "Items")> _ 
    Public Class XmlNodeItemList 
        Inherits ObservableCollection(Of XmlNodeItem) 
        Public Sub AddRange(ByVal range As IEnumerable(Of XmlNodeItem)) 
            For Each node As XmlNodeItem In range 
                Me.Add(node) 
            Next 
        End Sub 
    End Class 

Create a new class named RadComboBoxXmlDataSource, which derives from XmlNodeItemList. Practically, this will be the data source for the RadComboBox. The class takes a path to the XML file and deserializes the data in the private method RetrieveData().

public class RadComboBoxXmlDataSource : XmlNodeItemList 
{ 
    private string source; 
 
    public string Source 
    { 
        get 
        { 
            return this.source; 
        } 
        set 
        { 
            this.source = value; 
            AddRange(this.RetrieveData(Application.GetResourceStream(new Uri(value, UriKind.Relative)).Stream)); 
        } 
    } 
 
    private XmlNodeItemList RetrieveData( Stream xmlStream ) 
    { 
        XmlSerializer serializer = new XmlSerializer( typeof( XmlNodeItemList ) ); 
        StreamReader reader = new StreamReader( xmlStream ); 
        XmlNodeItemList list = ( XmlNodeItemList )serializer.Deserialize( reader ); 
        return list; 
    } 
} 
    Public Class RadComboBoxXmlDataSource 
        Inherits XmlNodeItemList 
        Private m_source As String 
 
        Public Property Source() As String 
            Get 
                Return Me.m_source 
            End Get 
            Set(ByVal value As String) 
                Me.m_source = value 
                AddRange(RetrieveData(Application.GetResourceStream(New Uri(value, UriKind.Relative)).Stream)) 
            End Set 
        End Property 
 
        Private Function RetrieveData(ByVal xmlStream As Stream) As XmlNodeItemList 
            Dim serializer As New XmlSerializer(GetType(XmlNodeItemList)) 
            Dim reader As New StreamReader(xmlStream) 
            Dim list As XmlNodeItemList = DirectCast(serializer.Deserialize(reader), XmlNodeItemList) 
            Return list 
        End Function 
    End Class 
  • The next step is to declare the RadComboBoxXmlDataSource as a resource in your application. Don't pass a valid string url to the Source property.

<UserControl.Resources> 
    <example:RadComboBoxDataSource x:Key="DataSource"  Source="RadComboBoxBindingToXml.xml"/> 
</UserControl.Resources> 
  • Update your RadComboBox declaration - set the ItemsSource property.

<telerik:RadComboBox x:Name="radComboBox" Width="200" ItemsSource="{Binding Source={StaticResource DataSource}}"/> 
  • The last step is to create a custom DateTemplate and set it to the RadComboBox's ItemTemplate property. Without it, the RadComboBox won't know how to interpret the data source.

For more information about the RadComboBox binding support, take a look at the DataBinding Support Overview topic.

<DataTemplate x:Key="ComboBoxCustomTemplate"> 
    <StackPanel Margin="5" Orientation="Horizontal"> 
        <TextBlock Text="{Binding Team}" Foreground="Blue"/> 
        <TextBlock Text=" ("/> 
        <TextBlock Text="{Binding Country}"/> 
        <TextBlock Text=")"/> 
    </StackPanel> 
</DataTemplate> 
  • Update your RadComboBox declaration for the last time and set its ItemTemplate property.

<telerik:RadComboBox x:Name="radComboBox" Width="200" ItemsSource="{Binding Source={StaticResource DataSource}}" ItemTemplate="{StaticResource ComboBoxCustomTemplate}"/> 

The result is shown on the snapshot below.

Silverlight RadComboBox Bound to XML Data

See Also

In this article