写个Win8 Metro风格的RSS阅读器

今天尝试写一个Metro风格的RSS阅读器,数据源就用本博客的订阅地址吧,先上效果图:

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

 

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

MainPage是首页,一打开就显示博客标题和文章列表。

MainPage.xaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
< 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
< 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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这个类,就是个数据实体,其实从前面赋值的代码里已经能推断出来了。 

1
2
3
4
5
6
7
8
9
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 

 







     本文转自 BoyTNT 51CTO博客,原文链接:http://blog.51cto.com/boytnt/860937,如需转载请自行联系原作者


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值