且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

写个Win8 Metro风格的RSS阅读器

更新时间:2022-09-26 09:21:34

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

写个Win8 Metro风格的RSS阅读器

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

写个Win8 Metro风格的RSS阅读器

 

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

写个Win8 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 { getset; } 
        public string Link { getset; } 
    
}



PPPS:最近加了搜索功能,见文章http://boytnt.blog.51cto.com/966121/892682 

 







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