Click here to Skip to main content
Click here to Skip to main content

XML Binding in WPF with Sample RSS Reader

, 18 Jul 2010
Rate this:
Please Sign up or sign in to vote.
XAML is getting more and more popular and has also been introduced for Mobile applications. Recently, while I was exploring the internet, I found that the recent version of Windows 7 mobile interfaces use Silverlight to deal with the interface...

XAML is getting more and more popular and has also been introduced for Mobile applications. Recently, while I was exploring the internet, I found that the recent version of Windows 7 mobile interfaces use Silverlight to deal with the interface. Just after the initial thought, I thought of trying it just to increase my knowledge base. Hence, I installed it on my machine and tried. It works great and I am really excited to see that Silverlight is again introduced with this mobile.

Inspite of having XNA for truely 3D style of application building, I tried simple programs to use this edition of Silverlight and it worked great. It works in the most simplest way as with normal Silverlight applications.

While doing the simple application, I found the XML binding within WPF application as an interesting part of XAML bindings. In this post, I will discuss how you can implement binding of a property with an XMLDataSource.

XML is a very important part for any application. While you create your application, we generally need to write a lot of code to handle XML data stream. May be from your local machine, or using WebClient to download data from your web server. WPF has in built support for XML bindings. Let's discuss XML bindings in detail using sample code.

Say you have an XML like this:

<data>
  <packet id="names">
    <Names description="All are selected">
      <nametype id="1" firstname="raja" lastname="das">58</nametype>
      <nametype id="2" firstname="anjan" lastname="chowdhuri">67</nametype>
      <nametype id="3" firstname="charu" lastname="singh">38</nametype>
      <nametype id="4" firstname="manju" lastname="sen">69</nametype>
      <nametype id="5" firstname="sanju" lastname="sharma">89</nametype>
      <nametype id="6" firstname="sanjana" lastname="mathur">77</nametype>
    </Names>
  </packet>
</data>

Now let us create a code that binds each element of the above XML.

<Window.Resources>
        <XmlDataProvider Source="myxmldata.xml" 
	x:Key="xdata" XPath="/data/packet/Names"></XmlDataProvider>
    </Window.Resources>

So first of all we have added a new window, and added the XmlDataSource as resource. Please note that we can also use x:Data to define the XmlDataSource XML directly within the file itself like:

<XmlDataProvider x:Key="xdata" XPath="/data/packet/Names">
            <x:XData>
                <data xmlns="">
                    <packet id="names">
                        <Names description="All are selected">
                            <nametype id="1" firstname="raja" 
				lastname="das">58</nametype>
                            <nametype id="2" firstname="anjan" 
				lastname="chowdhuri">67</nametype>
                            <nametype id="3" firstname="charu" 
				lastname="singh">38</nametype>
                            <nametype id="4" firstname="manju" 
				lastname="sen">69</nametype>
                            <nametype id="5" firstname="sanju" 
				lastname="sharma">89</nametype>
                            <nametype id="6" firstname="sanjana" 
				lastname="mathur">77</nametype>
                        </Names>
                    </packet>
                </data>
            </x:XData>
        </XmlDataProvider>

Please note that I have added the xmlns in data tag intentionally, as if you don't the XML will inherit from the base namespace.
The XPath within the XmlDataProvider induces the read of XML from that path. So for our XML, the data will be read after /data/packet/names.

So let's begin with bindings.

<Grid DataContext="{StaticResource xdata}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <TextBlock Text="{Binding XPath=@description, 
		StringFormat='{}Status: {0}'}" Grid.Row="0"/>
        <ListBox x:Name="lstNames" ItemsSource="{Binding XPath=nametype}" 
		IsSynchronizedWithCurrentItem="True" Grid.Row="1" 
		SelectionChanged="lstNames_SelectionChanged">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock>
                        <TextBlock.Text>
                            <MultiBinding StringFormat="{}{0} {1} Got {2}">
                                <Binding XPath="@firstname"></Binding>
                                <Binding XPath="@lastname"></Binding>
                                <Binding XPath="text()"></Binding>
                            </MultiBinding>
                        </TextBlock.Text>
                    </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <StatusBar Grid.Row="2">
            <TextBlock Text="Roll Number :"></TextBlock>
            <TextBlock x:Name="txtRoll"></TextBlock>
            <Separator/>
            <TextBlock Text="You Got : "></TextBlock> 
            <TextBlock Text="{Binding ElementName=lstNames, 
			Path=SelectedItem.InnerText}"/> 
        </StatusBar>
    </Grid>

In the above XAML code, you can see that I have put the datacontext of the Grid to the XmlDataProvider resource.

Keep in mind @ is used for attributes and / is used for tags. So the first TextBlock shows @description which means the string written within the description attribute of Names tag.

Now as we are in a collection of names, let's take a listbox to show all the elements within the XML data. The ItemsSource allows you to bind data with specific XPath. Here we have used nametype, as our main collection is of nametype. Within the datatemplate, we place one TextBlock for which the data is multi-bound. We use firstname and lastname attribute to put binding on the TextBlock Text property. In this situation, you can see, I have used @firstname and @lastname which will ensure that the binder will evaluate the Attribute rather than the innerText. The StatusBar allows you to show the bound data for the SelectedItem of the ListBox.

Things to Remember

  1. Use XPath to move to a particular node path.
  2. Move to currentElement using XPath and choose @ for attribute and text() to get the InnerText.
  3. / is used to move to the child nodes.
  4. In case you define your XML within XAML, be sure to specify the namespace to blank. Otherwise it will inherit from XAML namespace.

A little RSS Reader:

So as things are now clear, let us build a sample RSS reader.

RSS is a special XML schema, so when we load RSS into our XMLDataProvider, we need to parse it in a special format. So let us see how the XAML looks like:

<Window.Resources>
        <XmlDataProvider x:Key="dnt" 
                     Source="http://www.abhisheksur.com/feeds/posts/default?alt=rss" 
                     XPath="/rss/channel" />
    </Window.Resources>
    <StackPanel DataContext="{Binding Source={StaticResource dnt}}">
        <StackPanel>
            <TextBlock Text="Title : " />
            <Label Content="{Binding XPath=title}"/>
            <TextBlock Text="Description : "/>
            <Label Content="{Binding XPath=description}"/>
        </StackPanel>
        <ListBox    IsSynchronizedWithCurrentItem="True" 
                    ItemsSource="{Binding XPath=item}"
                    MaxHeight="500" 
                    ScrollViewer.CanContentScroll="False">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding XPath=title}" FontSize="30" />
                        <TextBlock Text="{Binding XPath=link}" FontSize="12" />
                        <Expander Header="Read..">
                            <TextBlock Text="{Binding XPath=./description}" 
				TextWrapping="Wrap" TextTrimming="WordEllipsis" 
				MaxWidth="520"/>
                        </Expander>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
</StackPanel>

The sample code looks almost similar to what we have already discussed. The major difference is how you parse the XML coming from the RSS feed. Here the XMLDataProvider points to an external Web address. The program once started takes a second to load the RSS from the external source. Once it is loaded, the specific nodes are bound to the Title, description and items shown on the ListBox.

I hope this would help you understanding how you could load your XML using Binding.
If you have any queries, please let me know. Thanks for reading.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Abhishek Sur
Architect
India India
Did you like his post?
 
Oh, lets go a bit further to know him better.
Visit his Website : www.abhisheksur.com to know more about Abhishek.
 
Abhishek also authored a book on .NET 4.5 Features and recommends you to read it, you will learn a lot from it.
http://bit.ly/EXPERTCookBook
 
Basically he is from India, who loves to explore the .NET world. He loves to code and in his leisure you always find him talking about technical stuffs.
 
Presently he is working in WPF, a new foundation to UI development, but mostly he likes to work on architecture and business classes. ASP.NET is one of his strength as well.
Have any problem? Write to him in his Forum.
 
You can also mail him directly to abhi2434@yahoo.com
 
Want a Coder like him for your project?
Drop him a mail to contact@abhisheksur.com
 
Visit His Blog

Dotnet Tricks and Tips



Dont forget to vote or share your comments about his Writing
Follow on   Twitter   Google+

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 18 Jul 2010
Article Copyright 2010 by Abhishek Sur
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid