上次随笔写了一个简易的 Windows 8 RSS 阅读器,本次随笔将改写一个简易的 Windows Phone 7 RSS 阅读器
同样是先贴出运行截图,共两个页面。
主页MainPage.xaml截图:
详细页Detail.xaml截图:
上面详细内容的显示也是使用浏览器控件。
与win8 WebView 不同的是WP7的浏览器控件叫WebBrowser,另外win8 WebView中如果点击超链接的target不等于_self则会打开电脑上自带的浏览器,而WP7的WebBrowser没这个问题,但WebBrowser对中文的支持还有不完善的地方,我在代码注释中会提到。
下面就贴出代码
App.xaml 中加了一段自定义的资源:
<!--应用程序资源--> <Application.Resources> <system:String x:Key="AppName">WP7RSS阅读器</system:String> <system:Double x:Key="fontSize1">25</system:Double> <Style TargetType="TextBlock"> <Setter Property="FontSize" Value="{StaticResource fontSize1}"/> <Setter Property="VerticalAlignment" Value="Center"/> </Style> </Application.Resources>
在App.xaml.cs中加了一个属性,用来页面间传递数据:
/// <summary> /// 要显示详细内容的RSS项 /// </summary> public static SyndicationItem RssItem { get; set; }
MainPage.xaml代码如下:
MainPage.xaml
<phone:PhoneApplicationPage x:Class="WP7RssReader.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" shell:SystemTray.IsVisible="True"> <!--LayoutRoot 是包含所有页面内容的根网格--> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--TitlePanel 包含应用程序的名称和页标题--> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="{StaticResource AppName}" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="RSS标题列表" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> <!--ContentPanel - 在此处放置其他内容--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Text="RSS地址:"/> <TextBox x:Name="txtFeedUri" Text="http://www.cnblogs.com/rss"/> </StackPanel> <Button x:Name="btnGetFeed" Content="加载RSS" Click="btnGetFeed_Click"/> <StackPanel Orientation="Horizontal" Grid.Row="2"> <TextBlock Text="提示信息:"/> <TextBlock x:Name="txtMsg" Text="暂无" /> </StackPanel> <StackPanel Orientation="Horizontal" Grid.Row="3"> <TextBlock Text="RSS标题:"/> <TextBlock x:Name="txtFeedTitle" Text="暂无" /> </StackPanel> <StackPanel Orientation="Horizontal" Grid.Row="4"> <TextBlock Text="内容条数:"/> <TextBlock x:Name="txtCount" Text="暂无" /> </StackPanel> </StackPanel> <ListBox x:Name="listTitle" SelectionChanged="listTitle_SelectionChanged" Grid.Row="1" BorderBrush="Gray" BorderThickness="1" FontSize="{StaticResource fontSize1}"> <ListBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Title.Text}" TextWrapping="Wrap" Margin="0,10"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </Grid> </phone:PhoneApplicationPage>
MainPage.xaml.cs代码如下:
MainPage.xaml.cs
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using System.ServiceModel.Syndication; using System.IO; using System.Xml; namespace WP7RssReader { public partial class MainPage : PhoneApplicationPage { public MainPage() { InitializeComponent(); } private void btnGetFeed_Click(object sender, RoutedEventArgs e) { string rssUrl = txtFeedUri.Text; if (string.IsNullOrWhiteSpace(rssUrl)) { txtMsg.Text = "RSS地址不能为空"; return; } Uri uri; if (!Uri.TryCreate(rssUrl, UriKind.Absolute, out uri)) { txtMsg.Text = "url错误"; return; } txtMsg.Text = "开始下载..."; btnGetFeed.IsEnabled = false; WebClient webClient = new WebClient(); webClient.DownloadStringCompleted += webClient_DownloadStringCompleted; webClient.DownloadStringAsync(uri); } void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { if (e.Error != null) { Deployment.Current.Dispatcher.BeginInvoke(() => { txtMsg.Text = e.Error.Message; }); } else { this.State["feed"] = e.Result; UpdateFeedList(e.Result); } txtMsg.Text = "下载完成"; btnGetFeed.IsEnabled = true; } protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { if (this.State.ContainsKey("feed")) { if (listTitle.Items.Count == 0) { UpdateFeedList(State["feed"] as string); } } if (listTitle.SelectedItem != null) { listTitle.SelectedItem = null; } } private void UpdateFeedList(string feedXML) { StringReader stringReader = new StringReader(feedXML); XmlReader xmlReader = XmlReader.Create(stringReader); SyndicationFeed feed = SyndicationFeed.Load(xmlReader); Deployment.Current.Dispatcher.BeginInvoke(() => { var title = feed.Title; txtFeedTitle.Text = title != null ? title.Text : "(没有标题)"; txtCount.Text = feed.Items.Count().ToString(); listTitle.ItemsSource = feed.Items; btnGetFeed.Content = "刷新RSS"; }); } private void listTitle_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (listTitle.SelectedValue != null) { App.RssItem = (SyndicationItem)listTitle.SelectedItem; NavigationService.Navigate(new Uri("/Detail.xaml", UriKind.Relative)); } } } }
Detail.xaml代码如下:
Detail.xaml
<phone:PhoneApplicationPage x:Class="WP7RssReader.Detail" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" shell:SystemTray.IsVisible="True"> <!--LayoutRoot 是包含所有页面内容的根网格--> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--TitlePanel 包含应用程序的名称和页标题--> <StackPanel Grid.Row="0" Margin="12,17,0,28"> <TextBlock Text="{StaticResource AppName}" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock Text="详细内容" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> <!--ContentPanel - 在此处放置其他内容--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock x:Name="txtTitle" TextWrapping="Wrap"/> <TextBlock x:Name="txtAuthor" TextWrapping="Wrap" Grid.Row="1"/> <phone:WebBrowser x:Name="WebBrowser1" Grid.Row="2"/> </Grid> </Grid> </phone:PhoneApplicationPage>
Detail.xaml.cs代码如下:
Detail.xaml.cs
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Navigation; using Microsoft.Phone.Controls; using Microsoft.Phone.Shell; using System.ServiceModel.Syndication; using System.IO; using System.Text; namespace WP7RssReader { public partial class Detail : PhoneApplicationPage { public Detail() { InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { var item = App.RssItem; txtTitle.Text = item.Title.Text; var authors = item.Authors; StringBuilder sb = new StringBuilder(); sb.Append("作者:"); foreach (var author in authors) { sb.Append(author.Name + " "); } sb.Remove(sb.Length - 1, 1); txtAuthor.Text = sb.ToString(); string content = "(没有内容)"; if (item.Content != null) { content = ((TextSyndicationContent)item.Content).Text; } else if (item.Summary != null) { content = item.Summary.Text; } content = ConvertExtendedAscii(content); WebBrowser1.NavigateToString(content); } /// <summary> /// 解决乱码问题,将编码大于127的字符转换成HTML的字符实体 /// </summary> /// <param name="html"></param> /// <returns></returns> private static string ConvertExtendedAscii(string html) { StringBuilder sb = new StringBuilder(); foreach (var c in html) { int charInt = Convert.ToInt32(c); if (charInt > 127) sb.AppendFormat("&#{0};", charInt);//&#entity_number; else sb.Append(c); } return sb.ToString(); } } }
解决方案打包下载:WP7RssReader.zip