第一个win8 Metro Style小程序
昨天把杨中科老师的《传智播客.net培训Windows 8开发视频教程》看完了,感觉还不错。下午有空写了一个小程序练练手。
首先看下效果
本次程序主要是将XML数据显示出来,开发步骤如下:
1、模型(Model)的创建
对于创建具有可持续性和和可维护性的应用程序,模型是必须具有的一个基础部分,它可以让我将应用程序数据与呈现数据给用户的方法相分离。如果不使用模型的话,你会发现你的程序越来越难以维护和开发。本例中将XML文件反序列化成一个Model列表(List<Model>),这个列表为ListView的数据源。
1 namespace BookViewDemo.Model 2 { 3 [XmlRootAttribute(ElementName = "Book", IsNullable = false)] 4 public class BookModel 5 { 6 7 private string _title; 8 private string _defaultPic; 9 private string _author; 10 private string _translator; 11 private string _publisher; 12 private DateTime _pubdate; 13 private string _price; 14 private string _pages; 15 private string _summary; 16 private string _author_intro; 17 [XmlAttribute] 18 public string ID { get; set; } 19 20 [XmlElement] 21 public string Title 22 { 23 get { return _title; } 24 set { _title = value; } 25 } 26 27 [XmlElement] 28 public string DefaultPic 29 { 30 get { return _defaultPic; } 31 set { _defaultPic = value; } 32 } 33 34 [XmlElement] 35 public string Author 36 { 37 get { return _author; } 38 set { _author = value; } 39 } 40 41 /// <summary> 42 /// 翻译 43 /// </summary> 44 [XmlElement] 45 public string Translator 46 { 47 get { return _translator; } 48 set { _translator = value; } 49 } 50 51 /// <summary> 52 /// 出版社 53 /// </summary> 54 [XmlElement] 55 public string Publisher 56 { 57 get { return _publisher; } 58 set { _publisher = value; } 59 } 60 61 [XmlElement] 62 public DateTime Pubdate 63 { 64 get { return _pubdate; } 65 set { _pubdate = value; } 66 } 67 68 [XmlElement] 69 public string Price 70 { 71 get { return _price; } 72 set { _price = value; } 73 } 74 75 [XmlElement] 76 public string Pages 77 { 78 get { return _pages; } 79 set { _pages = value; } 80 } 81 82 83 [XmlElement] 84 public string Author_intro 85 { 86 get { return _author_intro; } 87 set { _author_intro = value; } 88 } 89 90 [XmlElement] 91 public string Summary 92 { 93 get { return _summary; } 94 set { _summary = value; } 95 } 96 }
[XmlRootAttribute(ElementName = “Book”, IsNullable = false)] [XmlAttribute] 这些标记是XML序列化需要用到的,有兴趣可以去查阅XML序列化方面的资料
2、添加页面
a) 添加MainPage.xaml主要显示图书列表。
b) 添加BookDetail.xaml,主要现实图书详细内容
3、编写XAML
MainPage.xaml
<ListView HorizontalAlignment="Left" Margin="41,38,0,0" VerticalAlignment="Top" x:Name="lstBook" SelectionChanged="lstBook_SelectionChanged"> <ListView.ItemTemplate> <DataTemplate> <StackPanel Orientation="Vertical" Width="300" Height="300" VerticalAlignment="Center" HorizontalAlignment="Center" Background="White"> <Image Source="{Binding DefaultPic}" Width="250" Height="250" /> <Border Background="Black" Height="30" VerticalAlignment="Bottom"> <TextBlock Text="{Binding Title}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" Padding="10,0,0,0" /> </Border> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView>
BookDetail.xaml
<TextBlock Grid.Column=”1″ HorizontalAlignment=”Left” Margin=”330,24,0,0″ TextWrapping=”Wrap” Text=”{Binding Translator}” VerticalAlignment=”Top” Style=”{StaticResource ItemTextStyle}”/>
主要是一些TextBlock,Image控件的摆放,此处代码略。
4、编写页面相关代码
MainPage.xaml.cs
using System; using System.Collections.Generic; using System.IO; using System.Linq; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.Storage; 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 System.Xml.Serialization; using DoubanAPI.Model; namespace BookViewDemo { /// <summary> /// 可用于自身或导航至 Frame 内部的空白页。 /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } /// <summary> /// 在此页将要在 Frame 中显示时进行调用。 /// </summary> /// <param name="e">描述如何访问此页的事件数据。Parameter /// 属性通常用于配置页。</param> protected override async void OnNavigatedTo(NavigationEventArgs e) { XmlSerializer xs = new XmlSerializer(typeof(List<BookModel>)); List<BookModel> books = new List<BookModel>(); StorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation; StorageFile file = await folder.GetFileAsync(@"Assets\1.xml"); using (Stream stream = await file.OpenStreamForReadAsync()) { books = xs.Deserialize(stream) as List<BookModel>; } lstBook.ItemsSource = books; } private void lstBook_SelectionChanged(object sender, SelectionChangedEventArgs e) { BookModel selectBook = e.AddedItems[0] as BookModel; if (selectBook != null) { Frame.Navigate(typeof(BookDetail), selectBook); } } } }
StorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFile file = await folder.GetFileAsync(@”Assets\1.xml”);
在win8中读写文件都是异步方式,本例中读取工程中Assets\1.xml 文件,大家可以修改此处使用HttpClient获取远程XML
using (Stream stream = await file.OpenStreamForReadAsync())
{
books = xs.Deserialize(stream) as List<BookModel>;
}
在写到这个时候碰到难题,以前都是讲Model序列化成XML,再反序列化成Model没有任何问题,这次XML是我手写的却无法反序列化。
[http://www.devdiv.com/Windows8_MetroStyle_App_XML序列化问题-thread-166708-1-1.html]
于是我写了一个测试方法,将Model序列化成XML并保存在“文档”中
StorageFolder folder = KnownFolders.DocumentsLibrary; //使用此方法需要在Package.appxmanifest指定相应权限 详细:http://blog.csdn.net/beyondvincent/article/details/7957226
StorageFile file = await folder.CreateFileAsync(“1.xml”);
using (var result = await file.OpenStreamForWriteAsync())
{
xs.Serialize(result, bb); //bb是List<BookModel>
}
序列化得到的XML文件,在根据得到的XML文件进行修改
<?xml version="1.0"?> <ArrayOfBookModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <BookModel> <Title>玻璃钥匙</Title> <DefaultPic>http://img3.douban.com/mpic/s20604315.jpg</DefaultPic> <Author>达希尔·哈米特</Author> <Translator>周莎</Translator> <Publisher>新星出版社</Publisher> <Pubdate>2012-11-10T00:00:00</Pubdate> <Price>Price</Price> <Pages>Pages</Pages> <Author_intro>文学成就比肩海明威、福克纳、马尔克斯的大师改变侦探小说书写规则,引领“美国革命”的巨匠硬汉派小说鼻祖,“黑色电影”的创始人被誉为欧美侦探文学最后一位先知达希尔·哈米特全名萨缪尔·达希尔·哈米特,出生于美国马里兰州西岸的圣玛利县,在费城和巴尔的摩长大。 哈米特十三岁辍学,之后数年间做过报童、码头装卸工、机关勤杂人员和证券公司小职员,后来加入位于巴尔的摩的“平克顿全国侦探事务所”。一九一五年至一九二一年期间,他在平克顿事务所任职,这段经历为他后来创作侦探小说提供了广泛的素材。在第一次世界大战期间,达希尔应召入伍,但是后来因结核病而被迫长期疗养,继而导致他的婚姻破裂。之后他开始依赖酒精,曾尝试广告业,最终踏上了写作一途。他贫寒的出身、在下层社会摸爬滚打的青年时代,以及在当时全美最大的平克顿侦探社任职多年所获得的丰富经验,使他的作品独树一帜,无可替代。哈米特的写作生涯可谓辉煌。正是他开创了书写“硬汉派”推理小说的先河。美国当代最重要的硬汉派大奖“达希尔·哈米特奖”便是以他的名字命名,他在硬汉派和犯罪小说史上的地位,相当于古典推理界的爱伦·坡加上柯南·道尔。他与同时代的雷蒙德·钱德勒一起,将硬汉侦探文学发展为现实主义色彩浓厚、广受读者喜爱的文学类型,随后这一类作品又衍生出许多旁支,诸如法庭程序小说、犯罪小说、警察小说、间谍小说和国际政治小说等。此类作品今日的繁荣,哈米特作为创始者之一,功不可没。哈米特一生只创作了五个长篇故事,一个中篇故事和一些短篇小说,但每一篇都成为影响深远的经典作品。在美国当时经济大萧条,社会风气日渐堕落,犯罪事件层出不穷的环境下,哈米特塑造的强硬而愤世嫉俗的侦探形象成为一种新型的英雄,为大众所广泛接受。他笔下的人物诸如萨姆·斯佩德,以及“大陆侦探社”中的无名探员都在侦探文学史上拥有重要的地位。哈米特不只是一个通俗小说家,更是一个继承了马克·吐温、梅尔维尔的书写传统,拥有海明威般凌厉写实的语言功力,擅长以跌宕起伏的节奏和简洁明快的文笔准确描绘生活百态的文学大师。哈米特曾在派拉蒙电影公司担任编剧,他的小说被多次搬上银幕,均取得巨大成功,其中《马耳他之鹰》获得三项奥斯卡大奖,成为黑白片的经典之作。哈米特也为派拉蒙公司创作了《十字街头》、《守望莱茵河》等电影剧本,亦广受赞誉。生活中的哈米特是一位激进的反法西斯分子,一九三四年完成小说《瘦子》之后便封笔投入左派运动。他于一九三七年加入美国,二战时入伍,退伍后一直致力于政治活动,并两次入狱。一九九九年,“美国文库”出版了《哈米特集》,收录了他的全部长篇小说,对达希尔·哈米特为美国文学所做出的贡献给予了充分的肯定。</Author_intro> <Summary>美国某市的大选期间,参议员之子惨遭杀害,箭头指向挟怨仇杀及选举阴谋,各方人马皆欲借机谋利。警方及嫌犯的亲友分别收到奇怪的匿名信,里面的内容都是对嫌犯不利的影射。眼看着嫌犯已经众叛亲离,甚至自己承认了犯罪,但对他始终有信心的的好友兼手下仍然以身试险,企图力挽狂澜。</Summary> </BookModel> </ArrayOfBookModel>
原来得知XML的规范根节点的命名ArrayOf+Model类名,每一项父节点为Model名称。
BookDetail.xaml
这个文件主要UI控件数据绑定,Sliverlight如果大量控件需要绑定数据,可以利用继承特性:this.DataContext指定数据源
/// <summary> /// 使用在导航过程中传递的内容填充页。在从以前的会话 /// 重新创建页时,也会提供任何已保存状态。 /// </summary> /// <param name="navigationParameter">最初请求此页时传递给 /// <see cref="Frame.Navigate(Type, Object)"/> 的参数值。 /// </param> /// <param name="pageState">此页在以前会话期间保留的状态 /// 字典。首次访问页面时为 null。</param> protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState) { BookModel book = navigationParameter as BookModel; this.DataContext = book; }
总结
这个实例主要是做简单的数据绑定工作。在实现上面走了弯路,如果单纯的读取XML数据,我会用LinQ to XML,还可以继续修改代码将读取本地文件改为读取远程XML。这个实例我放在我的SVN上面,大家可以交流交流。
https://124.228.60.39/svn/Win8Project/
账号密码:user