(X) Hide this SilverlightShow next training events: Getting started with the Silverlight 5 Beta - a free 1 hour webinar on May 11th, by Michael Crump. Join at 10 am PST.
XNA for Windows Phone 7 - a 3 day training by MCC Peter Kuhn. June 1-3, 9 am - 1.30 pm PST. Sign up early-bird for $199.
Skip Navigation LinksHome / Articles / View Article

Databinding and the SyndicationFeed class

+ Add to SilverlightShow Favorites
1 comments   /   aggregated from Silverlight Web Services Team on Apr 21, 2008  /  original article
(0 votes)
Categories: Tips and Tricks

I found a couple of nice databinding tricks with the SyndicationFeed class, while putting together a code sample. The sample has been posted on silverlight.net for some time now (click here and then look for "Syndication - RSS/Atom Feed Reader").

For those not familiar with it: databinding is the association of an instance of a type or collection with a WPF control. One-way bindings are useful if you update the type or collection programmatically, then the control will reflect the change automatically. Think about an app that gets search results from a web service and adds them to a collection. As the new search results get added to the collection, a list in the app's UI gets updated automatically. Two-way bindings are nice if you want to be able to keep the UI and underlying instance in sync, regardless of which one is being changed. Think about an app that maintains the user's information (name, address) in an instance of an object. You want to allow the user to update their data, so you populate the object instance properties and the UI updates automatically. Then the user types changes in the UI, and the object instance gets updated automatically.

With SyndicationFeed, our main databinding scenario involves one-way binding: you parse a feed into a SyndicationFeed instance, and you want to bind that to a UI list to display all the entries in the feed.

The first step is easy - bind the IEnumerable<SyndicationItem> collection SyndicationFeed.Items to a ListBox, by adding this in the XAML:

<ListBox x:Name="itemsList" ItemsSource="{Binding}" /

>

and this in the code-behind, assuming feed is an instance of SyndicationFeed:

// Set up databinding for list of items
itemsList.DataContext = feed.Items;

Now every item in the ListBox has an associated SyndicationItem. We create a DataTemplate to define the shape of each item in the ListBox.

<ListBox x:Name="itemsList" ItemsSource="{Binding}">
   <ListBox.ItemTemplate>
      <DataTemplate>
         <HyperlinkButton Content="{Binding Title.Text}}"
                         
NavigateUri="{Binding Links, Converter={StaticResource linkFormatter}}" />
         <TextBlock Text="{Binding Summary.Text, Converter={StaticResource htmlSanitizer}}" />
      DataTemplate>
   ListBox.ItemTemplate>
ListBox>

There are three uses of databinding to explore here. One thing to keep in mind that by default all bindings are one-way.

HyperlinkButton.Content to SyndicationItem.Title.Text

Both properties are of type string so setting up the binding is simple.

HyperlinkButton.NavigateUri to SyndicationItem.Links

The first property is a string and the second is Collection. This binding won't work and we're not allowed to index into Links in a binding: only "dotting down" is supported. 

Bindings support "converters", which allow us to map between the two properties in the binding. Here we define the linkFormatter converter, which simply takes the first link in the collection and returns that.

public

class LinkFormatter : IValueConverter
{
   public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   {
      // Get the first link - that's the link to the post
     
return ((Collection<SyndicationLink>)value)[0].Uri; 
   }

   public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   {
      throw new NotImplementedException();
   }
}

To use the converter in XAML, we declare it as a resource in the page, which causes it to be instantiated at runtime. Notice that we name the instance of the LinkFormatter class "linkFormatter", which is what we use in the binding itself.

<

UserControl x:Class="SyndicationFeedReader.Page"
            
xmlns="http://schemas.microsoft.com/client/2007"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:SyndicationFeedReader"
>
  
<UserControl.Resources>
     
<local:HtmlSanitizer x:Key="htmlSanitizer"/>
     
<local:LinkFormatter x:Key="linkFormatter"/>
  
UserControl.Resources>

TextBlock.Text to SyndicationItem.Summary.Text

In this case both properties are of type string, so the converter trick is not really needed. However, here we use the converter to strip out HTML markup and clean up the text to display. Again, the converter class needs to be declared as a resource, as shown above.

public

class HtmlSanitizer : IValueConverter
{
  
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   {
     
// Remove HTML tags and empty newlines and spaces
     
string returnString = Regex.Replace(value as string, "<.*?>", "");
      returnString =
Regex.Replace(returnString, @"\n+\s+", "\n\n");

      // Decode HTML entities
     
returnString = HttpUtility.HtmlDecode(returnString);

      return returnString;
   }

   public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   {
     
throw new NotImplementedException();
   }
}

Hope this trick is useful!

Yavor Georgiev
Program Manager
Connected Framework

Share


Comments

Comments RSS RSS
  • RE: Databinding and the SyndicationFeed class  

    posted by Neo42 on Aug 29, 2008 03:57

    Do you think this would let me connect to a google spreadsheet via atom feed to retreive and even UPDATE the google spreadsheet?  See my google group thread about it.  I want to use silverlight as a gui for a game, and host the turn based multiplayer game data on a google spreadsheet.

    http://groups.google.com/group/Google-Docs-Data-APIs/browse_thread/thread/0f65a5040837ff12?hl=en

Add Comment

 
 

   
  
  
   
Please add 5 and 6 and type the answer here: