今天尝试写一个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,如需转载请自行联系原作者