出差在外,晚上闲来无事,刚好可以趁这个机会把之前学的WP开发基础拿出来再练练手。于是决定开始这个ListViewDemo,一来是因为ListView是WP开发中极为重要的控件之一,需要多加练习;二来是刚好可以借助这个程序结构,把相关的一些技术串联起来练习。好了闲话少说,这就开始吧。
项目Github托管地址:
https://github.com/Asinta/ListViewDemo
在第一天的工作中,主要实现了以下几个功能:
1.新建一个空白应用项目并使用VS2013将其托管到Github上。
2.添加测试数据并实现相应数据模型。
3.实现XML文件数据的解析。
4.实现一个UserControl并设置为ListViewItem的DataTemplate。
5.实现一个CustomControl并设置为ListViewItem的DataTemplate。
6.实现列表数据的展示,完成第一天的基本功能,提交并同步到Github上。
1.新建一个空白应用项目并使用VS2013将其托管到Github上
前提条件是你得有一个Github账号,并且在本机上安装了Github的客户端,这样VS2013的团队资源管理器中才会出现Git的选项。具体请参考:
http://rogerdudler.github.io/git-guide/index.zh.html
在新建空白应用程序时,勾选上“新建Git存储库”选项,确定生成新项目。
在Github页面上找到自己头像右侧的“+”按钮,选择“New Repository”,新建一个存储库,记得不要选那个初始化一个README文件的选项,之前自己做的时候选上了后来遇到了问题,所以简单起见还是不要选了。
创建Repository成功后得到一个Url地址,把这个地址复制下来,推送代码的时候会用到。
回到VS,第一次生成空白项目,下面做我们首次推送。 在“团队资源管理器”中,点击项目名称,选择“更改”,可以看到所有项目文件都处于已更改未添加的状态,输入提交消息(如:首次提交),下拉菜单选择“提交与同步”,会提示你还没有配置远程库,将刚才的Url地址填进去确定,点击“同步”,可以看到已经开始了和Github的同步过程。完成后可以去Github上看一看是否已经同步成功,这样我们的第一个功能就完成了。
2.添加测试数据并实现相应数据模型
我们使用的测试数据是来自https://github.com/MS-UAP/cnblogs-UAP项目Shared - SampleData中的RecommendAuthors.xml文件,文件内容的一部分如下:
<?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom"> <title type="text">博客园_推荐博客</title> <id>uuid:0803f68f-33d9-4b2a-a3e2-f2bd8b4cb157;id=5855</id> <updated>2014-11-30T12:23:59Z</updated> <entry> <id>http://www.cnblogs.com/artech/</id> <title type="text">Artech</title> <updated>2014-10-21T15:48:00+08:00</updated> <link rel="alternate" href="http://www.cnblogs.com/artech/"/> <blogapp>artech</blogapp> <avatar>http://pic.cnblogs.com/face/u19327.jpg</avatar> <postcount>551</postcount> </entry> <entry> ...
这个XML文件的结构非常简单,于是我们建立的数据模型如下:
[XmlRoot("feed",Namespace="http://www.w3.org/2005/Atom")] public class RecommendAuthorsDS { [XmlElement("title")] public string Title { get; set; } [XmlElement("id")] public string Id { get; set; } [XmlElement("updated")] public string Updated { get; set; } [XmlElement("entry", typeof(Authors))] public List<Authors> Author { get; set; } } [XmlRoot("entry")] public class Authors { [XmlElement("id")] public string Id { get; set; } [XmlElement("title")] public string Title { get; set; } [XmlElement("updated")] public string Updated { get; set; } [XmlElement("link", typeof(Link))] public Link Link { get; set; } [XmlElement("blogapp")] public string Blogapp { get; set; } [XmlElement("avatar")] public string AvatarUri { get; set; } [XmlElement("postcount")] public string PostCount { get; set; } } [XmlRoot("link")] public class Link { [XmlAttribute("href")] public string HRef { get; set; } [XmlAttribute("rel")] public string Rel { get; set; } }
3.实现XML文件数据的解析
我们准备采用XmlSerializer的Deserialize方法来进行XML数据的反序列化解析,该方法有好几种重载形式,这里采用的是传入一个Stream参数来进行解析。该Stream参数是通过OpenStreamForReadAsync方法得到的。
public async static Task<RecommendAuthorsDS> LoadXmlAndParse(StorageFile xmlfile) { RecommendAuthorsDS RecommendAuthors = new RecommendAuthorsDS(); XmlSerializer ser = new XmlSerializer(typeof(RecommendAuthorsDS)); using(var fr = await xmlfile.OpenStreamForReadAsync()) return (RecommendAuthorsDS)(ser.Deserialize(fr)); }
传入的StorageFile参数可以通过
StorageFile sf = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///SampleData/RecommendAuthors.xml"));
获得。调试结果,正确获取了XML文件中的数据,进入下一步。
4.实现一个UserControl并设置为ListViewItem的DataTemplate
在项目上右击添加——新建项——用户控件(UserControl),命名“ListItemViewer”确定,生成了一个.xaml文件和一个.cs文件。
.xaml文件改写如下:
<UserControl x:Class="ListViewDemo.Controls.ListItemViewer" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:ListViewDemo.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="2*"/> </Grid.ColumnDefinitions> <Image x:Name="img_Avatar" Source="{Binding AvatarUri}" Width="40" Height="40" Stretch="Fill" VerticalAlignment="Center" HorizontalAlignment="Center"/> <Grid Grid.Column="1" Background="{StaticResource PhoneAccentBrush}" > <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <TextBlock x:Name="tbk_Title" Text="{Binding Title}"/> <TextBlock x:Name="tbk_Updated" Grid.Row="1" Text="{Binding Updated}"/> <TextBlock x:Name="tbk_PostCount" Grid.Row="2" Text="{Binding PostCount}"/> </Grid> </Grid> </UserControl>
然后回到MainPage.xaml的声明中添加
xmlns:view="using:ListViewDemo.Controls"
这个位置是你的UserControl文件放置的位置。
并定义资源:
<Page.Resources> <DataTemplate x:Name="ListViewItemUserTemplate"> <view:ListItemViewer/> </DataTemplate> <Style x:Name="ListViewItemStyle" TargetType="ListViewItem"> <Setter Property="FontSize" Value="15"/> <Setter Property="FontFamily" Value="Segoe UI" /> <Setter Property="Margin" Value="9.5,9.5,9.5,9.5" /> <Setter Property="HorizontalContentAlignment" Value="Stretch"/> <Setter Property="VerticalContentAlignment" Value="Stretch"/> </Style> </Page.Resources>
注意这里的HorizontalContentAlignment设置为Stretch可以保证每一列的水平方向宽度都是相等的。
接下来在页面布局里引用这个UserControl即可:
<Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock x:Name="tbk_title" Text="ListView Sample" Style="{StaticResource TitleTextStyle}"/> <TextBlock x:Name="tbk_demoDescription" Text=‘This demo is for ListView in WP8.1,and it will show you how to use ListView control.‘ TextWrapping="WrapWholeWords" Style="{StaticResource DescriptionTextStyle}" Grid.Row="1"/> <ListView Grid.Row="2" x:Name="lv_RecommendAuthors" ItemTemplate="{StaticResource ListViewItemUserTemplate}" ItemContainerStyle="{StaticResource ListViewItemStyle}" /> </Grid>
这样我们的UserControl就做好了。
5.实现一个CustomControl并设置为ListViewItem的DataTemplate
用过了UserControl,其实这里我们也可以使用CustomControl来做,右击项目添加——新建项——模板控件(TemplateControl也就是CustomControl),命名“ListItemControl”确定,得到了一个.cs文件和一个在Themes文件夹下的Generic.xml文件。我们需要在这个.xml文件中设计外观,由于xml无法所见即所得编辑外观,需要先想清楚再开始写代码,我们直接套用上一步的UserControl的代码:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:ListViewDemo.Controls"> <Style TargetType="local:ListItemControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:ListItemControl"> <Border BorderThickness="0,0,0,1" BorderBrush="{StaticResource PhoneAccentBrush}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="2*"/> </Grid.ColumnDefinitions> <Image x:Name="img_Avatar" Source="{Binding AvatarUri}" Width="40" Height="40" Stretch="Fill" VerticalAlignment="Center" HorizontalAlignment="Center"/> <Grid Grid.Column="1" Background="{ThemeResource PhoneAccentBrush}"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <TextBlock x:Name="tbk_Title" Text="{Binding Title}"/> <TextBlock x:Name="tbk_Updated" Text="{Binding Updated}" Grid.Row="1"/> <TextBlock x:Name="tbk_PostCount" Text="{Binding PostCount}" Grid.Row="2"/> </Grid> </Grid> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
这样一来,和UserControl一样,在MainPage.xaml中添加
<DataTemplate x:Name="ListViewItemTemplate"> <view:ListItemControl/> </DataTemplate>
和
<ListView Grid.Row="2" x:Name="lv_RecommendAuthors" ItemTemplate="{StaticResource ListViewItemTemplate}" ItemContainerStyle="{StaticResource ListViewItemStyle}"/>
即可。
6.实现列表数据的展示,完成第一天的基本功能,提交并同步到Github上
在页面的OnNavigatedTo响应函数中进行如下操作,将列表绑定到集合对象上即可。
RecommendAuthorsDS _recommendAuthors = new RecommendAuthorsDS(); StorageFile sf = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///SampleData/RecommendAuthors.xml")); _recommendAuthors = await LoadAndParseXml.LoadXmlAndParse(sf); lv_RecommendAuthors.ItemsSource = _recommendAuthors.Author;
另外为了保证Image控件的Source属性绑定为ImageSource对象,需要实现一个Converter:
class ImageUriConvertor : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { return (ImageSource)value; } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } }
并在Image的Binding中指定这个Converter即可。
效果如图所示:
第一天的功能做完了,第二天我们来实现点击事件的响应,增量加载以及分步加载的功能。同样的,切换到团队资源管理器,查看更改,填写提交消息,选择提交与同步。大功告成,碎觉。