Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

Building an RSS Reader for Windows Phone 7

I noticed that Sam over on the Silverlight Show posted about a Windows Phone 7 Series RSS Reader which uses the WebBrowser control to render the content. I figured that whilst that was a neat approach to displaying content an alternative would be to parse the feed, extract the content and display using a combination of TextBlock, Run and LineBreak elements. The following screenshot shows my blog being viewed using such an approach.

image 
Here’s the core code that makes this all happen. It uses the SyndicationFeed class to extract the posts – in my case I’ve just embedded the feed source as a text resource file (hence var rss = RssResources.BlogPosts, where RssResources is a reference to the designer generated wrapper). I then loop through looking for html tags, specifically end of paragraphs and images. I’m sure there’s a more elegant way of doing this but for demo purposes this did the trick.

        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            // Load RSS into a feed
            var rss = RssResources.BlogPosts;
            using(var strm = new System.IO.StringReader(rss))
            using(var reader = System.Xml.XmlReader.Create(strm))
            {
                var feed = System.ServiceModel.Syndication.SyndicationFeed.Load(reader);
                // Regular expression to look for html tags
                var tagFinder = new System.Text.RegularExpressions.Regex("<(.|\n)+?>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // Create the initial textblock
                var txt = new TextBlock() { TextWrapping = TextWrapping.Wrap };
                this.stackPanel1.Children.Add(txt);
                foreach (var item in feed.Items)
                {
                    // Add a title
                    txt.Inlines.Add(new Run() { FontWeight = FontWeights.Bold, Text = item.Title.Text });
                    txt.Inlines.Add(new LineBreak());
                    var itemText = item.Summary.Text;
                    var match = tagFinder.Match(itemText);
                    var startidx = 0;
                    while (match.Index >= 0 && match.Length > 0)
                    {
                        if (match.Value == "</p>" || match.Value == "<p />" || match.Value == "<br />")
                        {
                            // Found the end of a paragraph, so append this text to the textblock
                            var text = itemText.Substring(startidx, match.Index - startidx);
                            text = tagFinder.Replace(text, "");
                            txt.Inlines.Add(text);
                        }
                        else if (match.Value.Contains("<img"))
                        {
                            // Add the text up to the image tag
                            var text = itemText.Substring(startidx, match.Index - startidx);
                            text = tagFinder.Replace(text, "");
                            txt.Inlines.Add(text);

                            // Locate the url of the image
                            var idx = match.Value.IndexOf("src");
                            var url = match.Value.Substring(idx + 5, match.Value.IndexOf("\"", idx + 6) - (idx + 5));

                            // Create an image and add to stackpanel
                            var img = new Image() { Source = new BitmapImage(new Uri(url)) };
                            img.Width = this.scrollViewer1.ActualWidth / 2;
                            img.Stretch = Stretch.UniformToFill;
                            this.stackPanel1.Children.Add(img);

                            // Create a new textblock and add to stackpanel
                            txt = new TextBlock() { TextWrapping = TextWrapping.Wrap };
                            this.stackPanel1.Children.Add(txt);
                        }

                        // Look for the next tag
                        startidx = match.Index + match.Length;
                        match = tagFinder.Match(itemText, match.Index + 1);

                    }
                    // Add the remaining text
                    txt.Inlines.Add(itemText.Substring(startidx));

                    // Add some space before the next post
                    txt.Inlines.Add(new LineBreak());
                    txt.Inlines.Add(new LineBreak());
                }
            }
        }

Comments (2) -

  • rome tours

    5/15/2010 2:42:25 AM |

    I finally realized that this blog is worth reading

  • Monster headphones

    8/11/2010 11:27:56 PM |

    By visiting your webpage, the first impression for me is strong. I can't imagine when and why you share this great topic but don't spread it with social bookmarking. This information can be published as reference in online journal, or even in press release site. An early improvement in your site is great, can give us more time in your website. Would you mind if I capture several screenshot as my collection, because I've joined several researches? General purpose for me is to tell you about this discussion. My critical question for us is the resource that you have used to manage this site. In order to make great discussion, you are great because you post new topic in several areas. But, I suggest in giving personal opinion, please refer to big or authority sites, I am sure you will be fine in giving past or future experiences. In my environment, I am sure your capability to enrich people can be strong advantage for your future.

  • tiles

    1/31/2011 7:16:06 AM |

    Well I am convinced there is more to follow, this subject can not be satisfied by merely this information in your post Building an RSS Reader for Windows Phone 7. Good coverage like this constantly requires you to go for additional posts! Why didnt I remember about this? I would really want to study more on this theme.

Comments are closed