C# Corner

Building a Windows 8 RSS Reader

Eric Vogel walks through a soup-to-nuts demo for building a Metro-style RSS reader.

Back in October I covered the basics of the Windows Runtime and how to access it from .NET. Since readers have asked for more, I've decided to revisit the Windows Runtime, leveraging it to create a Windows 8 Metro-Style application.

The application is an RSS reader that utilizes WinRT.  I'll go in depth on how to build the application from scratch. Along the way, you'll learn how to bind data to a form using XAML and consume an RSS feed using WinRT.

The first order of business is to download the VisualStudio 11 DeveloperPreview. Next is the project structure setup. I opened Visual Studio 11, seen in Figure 1, and created a new C# Metro app through File-> New Project. I've named my project VSMWinRTDemo.UI.


[Click on image for larger view.]
Figure 1. The new C# Metro application dialog.

Building the RSS Client
Next, I added the RSS client project, which will consume an RSS feed. I added a new C# Class Library to the project (Figure 2) and named it VSMWinRTDemo.RSS.


[Click on image for larger view.]
Figure 2. Adding the RSS Class Library Project.
The RSS client will retrieve RSS items and RSS items will contain RSS links. I'll add the RSSLink class first, as the RSSItem class depends upon it. An RSSLink contains a Title and a Link.
In the constructor, I set the Title property to the absolute path of the link in the case where the title tag was absent. See Listing 1 for the full code.

Next I add the RSSItem class, which will represent an individual feed item. A feed item contains a title, one or more authors, content, a description, the publication date, and one or more links. See Listing 2 for the full code.

Next I add the RSSFeed class, which contains an aggregation of all items for the feed and a title. See Listing 3 for the full code.

Last, I'll add the RSSClient class, which is the heart of the RSS library. The RSSClient class contains one method, named GetFeeds, that retrieves all the feed items for the given feed URL. In addition, the method limits the number of feeds returned by the given maxItems variable.

To actually retrieve the RSS feed I use the WinRT SyndicationClient class from the Windows.Web.Syndication namespace. I use LINQ to transform the multiple authors and links that may be contained in an individual feed item. See Listing 4 for the full code.

User Interface
The next step is to get the UI project set up. First, I add a reference to the RSS project in the solution, as shown in Figure 3.


[Click on image for larger view.]
Figure 3. Adding the RSS project reference to the UI project.

The application will by default retrieve the VSM Column RSS feed. The user will be able to enter a new RSS feed and click on a Fetch button to update the RSS feed items displayed. When a user clicks on an RSS feed item, the associate link for the item will be passed and rendered by a WebView control.

Now I need to design the app layout. I'll be using a two-column layout with a single row and column header for the main navigation of the application. I've put in a WebView in the second column control that will be used to display the full Web page view of the RSS item. RSS items themselves will be displayed through a ListView control.

To allow flexibility in the layout of the RSS item display, I've chosen to use data binding. An RSSFeed object will be used as the primary DataContext for the page. All of this should look familiar if you've used data binding in either WPF or Silverlight. See Listing 5 for the full XAML markup for the MainPage.

You should now be able to run the application and see the image from Figure 4.


[Click on image for larger view.]
Figure 4. The application layout.
Populating the Form
The application isn't that exciting yet. The next order of business is to retrieve the initial RSSFeed and set the data context for the page. Open up MainPage.xaml.cs and add a using statement for the RSS project as follows:
using VSMWinRTDemo.RSS;

Next, I add a member variable to store the number of feeds to display and wired up an RSSClient instance for the page.

private int  _maxFeeds = 20;
RSSClient _client = new RSSClient();
In the MainPage class constructor, I wired up the SelectionChangedEvent for the ListView of RSS feed items and the Click event for the Fetch button. I also wired up the Loaded event of the page so that I can load the initial RSS feed.
 public  MainPage() 
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
FeedListView.SelectionChanged += new     SelectionChangedEventHandler(FeedListView_SelectionChanged);
FetchButton.Click += new RoutedEventHandler(FetchButton_Click);
}
Next, I add the GetFeeds method that retrieves the given number of feed items for an RSS feed URL and sets the DataContext of the MainPage to the returned RSSFeed instance.
  private async Task GetFeeds(string url)
{
     RSSFeed feeds = await _client.GetFeeds(url, _maxFeeds);
     this.DataContext = feeds;
}
Now I call the GetFeeds method in the Loaded event handler for the MainPage to load the VSM Columns RSS feed when the application first loads up.
  
  async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
     await GetFeeds("http://visualstudiomagazine.com/rss-feeds/columns.aspx"); 
}
In the Click event of the Fetch button, I check to make sure the user entered a URL and then call the GetFeeds method to retrieve and bind the RSSFeed.
private async void FetchButton_Click(object sender, RoutedEventArgs e)
 {
     if (!String.IsNullOrWhiteSpace(FeedUrl.Text))
     {
         await GetFeeds(FeedUrl.Text);
     }
 }
Lastly, in the SelectionChanged event of the FeedsListView, I get the selected item's link and navigate the WebView to the URI.
  void FeedListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
      ListView rssFeeds = (sender as ListView);
      RSSItem selectedItem = rssFeeds.SelectedItem as RSSItem;


     if (selectedItem != null && selectedItem.Links.Count > 0)
     {
         RSSItemWebView.Navigate(selectedItem.Links[0].Link);
     }
  }

See Listing 6 for the full code for MainPage class.

Your app should now look similar to Figure 5. Sit back and start reading some of your favorite RSS feeds from Windows 8!


[Click on image for larger view.]
Figure 5. The finished application.
What's Next?
Windows 8 application development is very similar to Silverlight development, allowing you to leverage your existing XAML knowledge as well as .NET expertise. WinRT includes a lot of common functionality that exists in Win32 and .NET today. In addition, there are some unique new features in Windows 8. Stay tuned for the next article, where I'll cover how to add a share contract to the app and store the feed locally for offline access.

About the Author

Eric Vogel is a Sr. Software Developer at Kunz, Leigh, & Associates in Okemos, MI. He is the president of the Greater Lansing User Group for .NET. Eric enjoys learning about software architecture and craftsmanship, and is always looking for ways to create more robust and testable applications. Contact him at vogelvision@gmail.com.

comments powered by Disqus

Reader Comments:

Sun, Oct 14, 2012 Wasp

Never mind. :D Fixed it, thanks. :)

Sun, Oct 14, 2012 Wasp

Hi, Thanks for your tutorial. In Listing 6, I get this error in this method: "private async Task GetFeeds(string url) { RSSFeed feeds = await _client.GetFeeds(url, _maxFeeds); this.DataContext = feeds; }" '_client' does not exist in this context. What is the error?

Wed, Oct 3, 2012 Amit Bangladesh

Awesome! Thanks for the tutorial :D

Sun, Sep 9, 2012 Toni

Same problem. Tried to find Windows.Web.Syndication but VS2012 can't locate. Is this an exclusive feature of Win8RC?

Thu, May 31, 2012 Houssem Dellai Tunisia

Thank you for the Tutorial. But it didn't work for me. Error=Partial declarations of 'RSSFeed6.BlankPage' must not specify different base classes.

Thu, Mar 15, 2012

I have tried to find where Windows.Web.Syndication is, but I could not find it.

Add Your Comments Now:

Your Name:(optional)
Your Email:(optional)
Your Location:(optional)
Comment:
Please type the letters/numbers you see above

.NET Insight

Sign up for our newsletter.

I agree to this site's Privacy Policy.