Displaying a RSS feed is a very straight forward task in Silverlight.
In summary: we need to access and download the RSS (XML file) and read it as a single string value, read the downloaded string as XML using XmlReader class, load the XML into a variable of type SyndicationFeed, and finally using a loop extract each node and save it in a desirable variable.
Some of the Silverlight built-in classes used in this example are:
| Uri: |
Takes the URL of the RSS feed |
| XmlReader: |
Represents a reader that provides fast, non-cached, forward-only access to XML data” (msdn) |
| SyndicationFeed: |
Represents a top-level feed object, <feed> in Atom 1.0 and <rss> in RSS 2.0” (msdn) |
| WebClient: |
Receives data from a recource defuned by Uri (in our case a URL to RSS or XML file) |
I am going to demonstrate how to read and display a RSS feed (XML file) in three simple steps:
Step 1: Create a custom RSS class
here I am just creating a new public class (RSSItem) for my RSS feed to contain any information I would like to keep for each item in the RSS. This will help to keep my project tidy and my code meaningful. In my RSSItem class I will add as many properties as I need:
public class RSSItem
{
#region Properties
public string RSSTitle {get; set;}
public string RSSDescription { get; set; }
public Uri RSSLink { get; set; }
#endregion
}
Step 2: Reading the RSS feed in Silverlightcreate three private variables for Uri, XmlReader and SyndicationFeed (for this you need to add a new reference in your project to System.ServiceModel.Syndication – do this by right clicking on ‘References’ folder in you Silverlight project and clicking on ‘Add Reference...’)
private Uri rssUri;
private XmlReader xmlReader;
private SyndicationFeed feed;
and don't forget to add the namespaces:
using System.Xml;
using System.ServiceModel.Syndication;
Now, in your constructor or ‘Loaded’ method add the following:
rssUri = new Uri("http://feeds.feedburner.com/Silverlighttips");
WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
client.DownloadStringAsync(rssUri);
WebClient is another built-in class in Silverlight and is used to open the XML (RSS). Since the operation is done asynchronously the callback method (DownloadStringCompleted) is called after the operation is done.
Step 3: Populate RSS nodes
first, add an ItemsControl in the MainPage.xaml:
<ItemsControl x:Name="RSS" ItemsSource="{Binding}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<HyperlinkButton x:Name="Title" NavigateUri="{Binding RSSLink}"
Width="305" Margin="0,22,0,15" Foreground="#FF10589F"
FontSize="12" FontWeight="Bold">
<HyperlinkButton.Content>
<TextBlock Text="{Binding RSSTitle}" TextWrapping="Wrap" />
</HyperlinkButton.Content>
</HyperlinkButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
In the ItemsControl we can bind the required properties from our RSSItem class using {Binding
nameOfProperty}.
Now, from our DownloadStringCompleted method in MainPage.xaml.cs we can retrieve the RSS in form of a string. Then, we can create our XmlReader and load it to a SyndicationFeed variable which treats the XML as a 'RSS' and allow us to use its properties:
private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
int itemsCount = 5;
xmlReader = XmlReader.Create(new StringReader(e.Result));
feed = SyndicationFeed.Load(xmlReader);
List<RSSItem> itemsList = new List<RSSItem>();
if (feed.Items.Count() < 5)
{
itemsCount = feed.Items.Count();
}
for (int i = 0; i <= itemsCount; i++)
{
RSSItem rssitem = new RSSItem();
rssitem.RSSTitle = feed.Items.ToList()[i].Title.Text;
rssitem.RSSLink = feed.Items.ToList()[i].Links[0].Uri;
itemsList.Add(rssitem);
}
RSS.ItemsSource = itemsList;
}
}
you will need to add the namespace for the StringReader:
using System.IO;
In the above method from top:
- check if there are any errors in the result, if not continue
- set the number of items to read
- load the XML into a SyndicationFeed variable
- create a new List of type RSSItem to hold each RSSItem
- if the number of total RSS items to be found (itemsCount) is greater than the total number of RSS items available then go with the total number of available items
- search in each node for ‘Title’ and ‘Summary’ (description)
- add Title and Summary of each RSS item to the variable of type RSSItem class, and finally add the rssitem to the RSSItem list
- at the end we bind our itemsList to 'RSS' which is an ItemsControl in our XAML page