您的位置:首页 > 其它

写个Win8 Metro风格的RSS阅读器 推荐

2012-05-11 16:49 218 查看
今天尝试写一个Metro风格的RSS阅读器,数据源就用本博客的订阅地址吧,先上效果图:



点击其中的文章,再显示内容:




功能挺简单,先看工程结构:



MainPage是首页,一打开就显示博客标题和文章列表。
MainPage.xaml:
<Page
x:Class="Rss.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Rss"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Name="rootPage">

<Grid Background="{StaticResource ApplicationPageBackgroundBrush}">
<!--分面上下两行,上面显示博客标题,下面显示文章列表-->
<Grid.RowDefinitions>
<RowDefinition Height="120"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>

<!--这个就是博客标题了-->
<TextBlock Name="pageTitle" Style="{StaticResource PageHeaderTextStyle}" Margin="30,20,0,0"></TextBlock>

<!--用GridView来承载文章列表,ItemsSource使用数据绑定方式,一会儿会把一个List<BlogArticle>赋值给它,所以绑定的是Value-->
<GridView Name="gvArticles" ItemsSource="{Binding Value}" Grid.Row="1" Padding="50" SelectionChanged="gvArticles_SelectionChanged">
<!--定义模板,放一个图片和一行文本-->
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel Margin="5">
<Image Width="120" Height="120" Source="ms-appx:///Assets/Article.png"></Image>
<!--文章标题又使用了数据绑定方式,绑定到BlogArticle.Title属性上-->
<TextBlock Text="{Binding Title}" TextWrapping="Wrap" Width="120"></TextBlock>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
</Page>


MainPage.xaml.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Data.Xml.Dom;

namespace Rss
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}

//页面加载时会调用OnNavigateTo方法,把它变成async的,因为里面要用异步方法
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
//拿HttpClient取rss的xml,WebClient这个类没有了。另外由于XmlDataProvider不能用了,所以只好自己解析并装载集合
var client = new HttpClient();
string url = "http://boytnt.blog.51cto.com/rss.php?uid=966121";

//注意51cto的rss是gbk编码的,所以不能直接client.GetStringAsync,会乱码,这里await关键字发威了~~
StreamReader reader = new StreamReader(await client.GetStreamAsync(url), Encoding.GetEncoding("gbk"));
string rss = await reader.ReadToEndAsync();
//XmlDocument也换到Windows.Data.Xml.Dom命名空间下了
XmlDocument xml = new XmlDocument();
xml.LoadXml(rss);

//解析title
pageTitle.Text = xml.SelectSingleNode("/rss/channel/title").InnerText;

//解析item,然后装入List<BlogArticle>中,图省事只装载了title和link两个节点
var articles = new List<BlogArticle>();
var nodes = xml.SelectNodes("/rss/channel/item");
foreach (var node in nodes)
{
var article = new BlogArticle()
{
Title = node.SelectSingleNode("title").InnerText,
Link = node.SelectSingleNode("link").InnerText
};
articles.Add(article);
}

//赋数据源
gvArticles.ItemsSource = articles;

//前面打开的StreamReader没关闭?是的,没有Close方法了  一_一#
}

private void gvArticles_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var articles = gvArticles.ItemsSource as List<BlogArticle>;
int index = gvArticles.SelectedIndex;

//跳转到ArticlePage去,并且把选中的文章作为参数传递过去
rootPage.Frame.Navigate(typeof(ArticlePage), articles[index]);
}
}
}


ArticlePage是内容页,用于显示文章内容,能回退到MainPage。
ArticlePage.xaml:
<common:LayoutAwarePage
x:Name="pageRoot"
x:Class="Rss.ArticlePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Rss"
xmlns:common="using:Rss.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Grid Background="{StaticResource ApplicationPageBackgroundBrush}">
<!--也分上下两行,上面显示回退按钮和标题,下面显示页面-->
<Grid.RowDefinitions>
<RowDefinition Height="120"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

<!--第一行放一个Grid,再分成两列,分别显示按钮和标题-->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<!--回退按钮使用了内置的样式-->
<Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
<TextBlock x:Name="pageTitle" Text="{Binding Group.Title}" Style="{StaticResource PageHeaderTextStyle}" Grid.Column="1"/>
</Grid>

<!--用WebView显示页面,现在没有WebBrowser了-->
<WebView Name="article" Grid.Row="1"></WebView>
</Grid>
</common:LayoutAwarePage>


ArticlePage.xaml.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace Rss
{
public sealed partial class ArticlePage : Rss.Common.LayoutAwarePage
{
public ArticlePage()
{
this.InitializeComponent();
}

protected override void OnNavigatedTo(NavigationEventArgs e)
{
//e.Parameter中是传过来的参数
var param = e.Parameter as BlogArticle;
pageTitle.Text = param.Title;
article.Source = new Uri(param.Link);
}
}
}


OK,Ctrl+F5运行吧。
PS:本文基于Win8 Consumer Preview + Visual Studio 11 Beta。
PPS:应小星同学强烈要求,补一下BlogArticle这个类,就是个数据实体,其实从前面赋值的代码里已经能推断出来了。
using System;
namespace Rss
{
public class BlogArticle
{
public string Title { get; set; }
public string Link { get; set; }
}
}


PPPS:最近加了搜索功能,见文章http://boytnt.blog.51cto.com/966121/892682
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  metro