导出 (0) 打印
全部展开

如何创建 Windows Phone 的基础 RSS 读取器

2012/2/9

您可以通过完成下列步骤来创建基础 RSS 读取器。本主题中的指南和代码示例基于名为 RSS 读取器示例的代码示例,该示例可以从 Windows Phone 的代码示例下载。

创建 Windows Phone 应用程序

  1. 在 Visual Studio 中,创建一个新的“Windows Phone 应用程序”项目。此模板在“Silverlight for Windows Phone”类别中。

  2. “Windows Phone OS 目标版本”下拉菜单中选择“Windows Phone OS 7.1”

若要使用 SyndicationFeed 类,您必须首先添加 DLL 引用。

向整合 DLL 中添加引用

  1. 从 Visual Studio 中的“项目”菜单中,选择“添加引用”,并选择“浏览”标签。

  2. 导航到“程序文件”目录。

  3. 导航到 Microsoft SDKs/Silverlight/v4.0/Libraries/Client/

  4. 选择“System.ServiceModel.Syndication.dll”并单击“确定”

    注意注意:

    如果在此步骤中您查看到一个询问您是否希望继续的提示,则单击“是”

RSS 源中的说明文本通常包含您可能不希望在 RSS 读取器中显示的 HTML、编码字符及其他数据。您可以创建一个排除 HTML 及其他不需要数据的类,并将其设置为 XAML 字段的转换器。

创建 RSS 文本裁边器

  1. “解决方案资源管理器”中,右键单击该项目名称,单击“添加”,然后单击“新项”

  2. “已安装的模板”窗格中选择“Visual C#”,然后在中间窗格中选择“类”

  3. 命名文件 RssTextTrimmer.cs,并单击“添加”

  4. “解决方案资源管理器”中双击 RssTextTrimmer.cs 文件。

  5. 添加以下命名空间:

    using System.Windows.Data;
    using System.Globalization;
    using System.Text.RegularExpressions;
    
    
  6. 更新类定义,以便它可以实现 IValueConverter 接口:

    public class RssTextTrimmer : IValueConverter
    
    
  7. 在 RssTextTrimmer 类中添加以下代码:

    // Clean up text fields from each SyndicationItem. 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null) return null;
    
        int maxLength = 200;
        int strLength = 0;
        string fixedString = "";
    
        // Remove HTML tags and newline characters from the text, and decode HTML encoded characters. 
        // This is a basic method. Additional code would be needed to more thoroughly  
        // remove certain elements, such as embedded Javascript. 
    
        // Remove HTML tags. 
        fixedString = Regex.Replace(value.ToString(), "<[^>]+>", string.Empty);
    
        // Remove newline characters.
        fixedString = fixedString.Replace("\r", "").Replace("\n", "");
    
        // Remove encoded HTML characters.
        fixedString = HttpUtility.HtmlDecode(fixedString);
    
        strLength = fixedString.ToString().Length;
    
        // Some feed management tools include an image tag in the Description field of an RSS feed, 
        // so even if the Description field (and thus, the Summary property) is not populated, it could still contain HTML. 
        // Due to this, after we strip tags from the string, we should return null if there is nothing left in the resulting string. 
        if (strLength == 0)
        {
            return null;
        }
    
        // Truncate the text if it is too long. 
        else if (strLength >= maxLength)
        {
            fixedString = fixedString.Substring(0, maxLength);
    
            // Unless we take the next step, the string truncation could occur in the middle of a word.
            // Using LastIndexOf we can find the last space character in the string and truncate there. 
            fixedString = fixedString.Substring(0, fixedString.LastIndexOf(" "));
        }
    
        fixedString += "...";
    
        return fixedString;
    }
    
    // This code sample does not use TwoWay binding, so we do not need to flesh out ConvertBack.  
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
    
    
  8. 通过在“解决方案资源管理器”中的双击“App.xaml”,并在<“Application.Resources”>标记中添加以下代码将 RssTextTrimmer 类设置为转换器:

    <converter:RssTextTrimmer xmlns:converter="clr-namespace:sdkRSSReaderCS" x:Key="RssTextTrimmer" />
    
    

    其中,“sdkRSSReaderCS”是项目的命名空间的名称。

更新 XAML 代码

  1. “解决方案资源管理器”中双击“MainPage.xaml”文件。

  2. <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid> 替换为下面的 XAML 代码:

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,12,0">
        <Button Content="Load Feed" Height="72" HorizontalAlignment="Left" Margin="9,6,0,0" Name="loadFeedButton" VerticalAlignment="Top" Width="273" Click="loadFeedButton_Click" />
    
        <ListBox Name="feedListBox" Height="468" HorizontalAlignment="Left" Margin="20,100,0,0" VerticalAlignment="Top" Width="444" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectionChanged="feedListBox_SelectionChanged">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel VerticalAlignment="Top">
                        <TextBlock TextDecorations="Underline" FontSize="24" Name="feedTitle" TextWrapping="Wrap" Margin="12,0,0,0" HorizontalAlignment="Left" Foreground="{StaticResource PhoneAccentBrush}" Text="{Binding Title.Text, Converter={StaticResource RssTextTrimmer}}" />
                        <TextBlock Name="feedSummary" TextWrapping="Wrap" Margin="12,0,0,0" Text="{Binding Summary.Text, Converter={StaticResource RssTextTrimmer}}" />
                        <TextBlock Name="feedPubDate" Foreground="{StaticResource PhoneSubtleBrush}" Margin="12,0,0,10" Text="{Binding PublishDate.DateTime}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Border BorderBrush="{StaticResource PhoneSubtleBrush}" BorderThickness="1" Height="2" HorizontalAlignment="Left" Margin="20,88,0,0" Name="border1" VerticalAlignment="Top" Width="438" />
    </Grid>
    
    

更新代码隐藏文件的步骤

  1. 添加以下命名空间:

    using System.IO;
    using System.ServiceModel.Syndication;
    using System.Xml;
    using Microsoft.Phone.Tasks;
    
    
  2. 将以下代码添加到 MainPage 类中,放在 MainPage 构造函数后面。

    注意注意:

    以下代码中还包括对基本逻辑删除的支持。

    // Click handler that runs when the 'Load Feed' or 'Refresh Feed' button is clicked. 
    private void loadFeedButton_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        // WebClient is used instead of HttpWebRequest in this code sample because 
        // the implementation is simpler and easier to use, and we do not need to use 
        // advanced functionality that HttpWebRequest provides, such as the ability to send headers.
        WebClient webClient = new WebClient();
    
        // Subscribe to the DownloadStringCompleted event prior to downloading the RSS feed.
        webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
    
        // Download the RSS feed. DownloadStringAsync was used instead of OpenStreamAsync because we do not need 
        // to leave a stream open, and we will not need to worry about closing the channel. 
        webClient.DownloadStringAsync(new System.Uri("http://windowsteamblog.com/windows_phone/b/windowsphone/rss.aspx"));
    }
    
    // Event handler which runs after the feed is fully downloaded.
    private void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                // Showing the exact error message is useful for debugging. In a finalized application, 
                // output a friendly and applicable string to the user instead. 
                MessageBox.Show(e.Error.Message);
            });
        }
        else
        {
            // Save the feed into the State property in case the application is tombstoned. 
            this.State["feed"] = e.Result;
    
            UpdateFeedList(e.Result);
        }
    }
    
    // This method determines whether the user has navigated to the application after the application was tombstoned.
    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        // First, check whether the feed is already saved in the page state.
        if (this.State.ContainsKey("feed"))
        {
            // Get the feed again only if the application was tombstoned, which means the ListBox will be empty.
            // This is because the OnNavigatedTo method is also called when navigating between pages in your application.
            // You would want to rebind only if your application was tombstoned and page state has been lost. 
            if (feedListBox.Items.Count == 0)
            {
                UpdateFeedList(State["feed"] as string);
            }
        }
    }
    
    // This method sets up the feed and binds it to our ListBox. 
    private void UpdateFeedList(string feedXML)
    {
        // Load the feed into a SyndicationFeed instance.
        StringReader stringReader = new StringReader(feedXML);
        XmlReader xmlReader = XmlReader.Create(stringReader);
        SyndicationFeed feed = SyndicationFeed.Load(xmlReader);
    
        // In Windows Phone OS 7.1, WebClient events are raised on the same type of thread they were called upon. 
        // For example, if WebClient was run on a background thread, the event would be raised on the background thread. 
        // While WebClient can raise an event on the UI thread if called from the UI thread, a best practice is to always 
        // use the Dispatcher to update the UI. This keeps the UI thread free from heavy processing.
        Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            // Bind the list of SyndicationItems to our ListBox.
            feedListBox.ItemsSource = feed.Items;
    
            loadFeedButton.Content = "Refresh Feed";
        });
    }
    
    // The SelectionChanged handler for the feed items 
    private void feedListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ListBox listBox = sender as ListBox;
    
        if (listBox != null && listBox.SelectedItem != null)
        {
            // Get the SyndicationItem that was tapped.
            SyndicationItem sItem = (SyndicationItem)listBox.SelectedItem;
    
            // Set up the page navigation only if a link actually exists in the feed item.
            if (sItem.Links.Count > 0)
            {
                // Get the associated URI of the feed item.
                Uri uri = sItem.Links.FirstOrDefault().Uri;
    
                // Create a new WebBrowserTask Launcher to navigate to the feed item. 
                // An alternative solution would be to use a WebBrowser control, but WebBrowserTask is simpler to use. 
                WebBrowserTask webBrowserTask = new WebBrowserTask();
                webBrowserTask.Uri = uri;
                webBrowserTask.Show();
            }
        }
    }
    
    

Microsoft 正在进行一项网上调查,以了解您对 MSDN 网站的意见。 如果您选择参加,我们将会在您离开 MSDN 网站时向您显示该网上调查。

是否要参加?
显示:
© 2014 Microsoft