在网格应用和拆分应用项目模板中,获取应用所需数据的代码位于 SampleDataSource.cs/vb/cpp 文件中。该文件表示应用的示例数据源。SampleDataSource 文件包含替换动态数据通常所需的静态数据。例如,如果应用发出单个请求以获取 RSS 数据,则你需要在 SampleDataSource 中包括此代码。包含此处的代码可以方便地使用自己的数据而不会更改显示在模板中的数据模型。
将自己的数据添加到应用时需要注意下面几项:
- 组和项目存在固有链接。应用会认为项目数据组织为多个组。可以在你自己的实现中对两者取消链接,但是需要修改代码使该实现可以完成。本主题将介绍模板数据模型中如何使用组。
- 为 SampleDataSource 中的应用实现自定义数据时,需要确保自定义数据固有的属性名称映射到模板使用的属性名称。可以更改模板使用的名称,但是这需要更多的代码修改。本主题提供了一些操作示例。
项目和组
网格应用和拆分应用围绕整理为项组的数据构建。 提供的 SampleDataSource 具有组的集合,每个组都由项集合组成。
SampleDataSource 中有如下四类:SampleDataCommon、SampleDataItem、SampleDataGroup 以及 SampleDataSource。 SampleDataItem 和 SampleDataGroup 都会扩展 SampleDataCommon。
SampleDataCommon 是保留对于项和组而言公用的属性的类。 这些属性包括 UniqueID、标题、副标题、描述以及图像。 此类通过利用一个其他类:BindableBase 来实现 INotifyPropertyChanged。 BindableBase 是公用目录中提供的一个类。 此类仅为 INotifyPropertyChanged 的实现。 在模板顶部进行扩展和构建时,请随意使用此基础。
通过将两个其他属性:content 和 pointer 添加回拥有该项的组,SampleDataItem 扩展了 SampleDataCommon 类。 同样通过添加两个其他属性,SampleDataGroup 扩展了 SampleDataCommon 类。 第一个属性是项(命名正确的项)集合。 第二个是一个集合,该集合镜像了项属性并仅具有顶部 12 个项(名为 TopItem)。 此集合用于 GroupedItemsPage,以便仅显示此页面上项的子集(用户可以深入了解 GroupDetailsPage 上的整个组)。
SampleDataSource 使用硬编码的静态内容创建项组集合。 它使用占位符数据而非实时生产数据初始化以在设计时和运行时提供数据。
如果你的数据紧密映射到已由 SampleDataItem 和 SampleDataGroup 提供的架构,则可以仅删除构造函数中的硬编码内容,改为按原样正确为你的应用初始化数据。 如果连接到设计时可能不能使用(或可能加载速度不够快)的实时数据,请记住在以下设计模式检查中隐藏任何调用,并且如果你希望看到设计图面上的数据,则提供备用示例数据:
public SampleDataSource() { if (Windows.ApplicationModel.DesignMode.DesignModeEnabled) { //Load runtime data here } else { //Load sample data here } }
将组和项数据绑定到用户界面
在模板中,数据通常通过默认 DataContext 绑定到 UI。 在每页中,在 LoadState() 事件中加载数据,同时调用静态数据成员 (SampleDataSource),如下所示:var item = SampleDataSource.GetItem((String)navigationParameter);
。
数据模板(在 StandardStyles.xaml 中定义)用于格式化并显示多个数据实例。每个数据模板都绑定到以 XAML 显式定义的属性。 下面是一个示例:
<!-- Grid-appropriate 250 pixel square item template as seen in the GroupedItemsPage and ItemsPage --> <DataTemplate x:Key="Standard250x250ItemTemplate"> <Grid HorizontalAlignment="Left" Width="250" Height="250"> <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}"> <Image Source="{Binding Image}" Stretch="UniformToFill"/> </Border> <StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}"> <TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/> <TextBlock Text="{Binding Subtitle}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/> </StackPanel> </Grid> </DataTemplate>
尤其需要了解的是,项目模板预期数据中显示某些属性,这些属性以 XAML 显式命名。在前面用于 GroupedItemsPage 和 ItemsPage 的 XAML 代码中,你可以找到诸如标题、副标题以及图像之类的属性。如果你的自定义应用数据不使用这些特定属性名称,则需要执行下列操作之一:
- 将你的数据映射到这些属性名称(一般在 SampleDataSource 中)。
- 修复模板代码中这些属性的所有 XAML 和代码引用,以使它们与你的数据中使用的属性名称相匹配。
将数据绑定到 UI 的示例
此部分显示如何在项目模板中实现自己的数据源。此处的示例代码使用请求生成 RSS 数据。
更新 SampleDataSource
- 在 Visual Studio 菜单上,单击“文件”>“新建项目”。
- 在“新建项目”对话框的左侧窗格中,展开 Visual C#、Visual Basic 或 Visual C++ 节点。
- 在中心窗格中,单击“网格应用”或“拆分应用”。
- 在“名称”框中,键入 DataModelExample,然后单击“确定”。
此刻,解决方案已创建并且项目文件显示在解决方案资源管理器中。有关项目文件的详细信息,请参阅适用于 Windows 应用商店应用的 C#、VB 以及 C++ 项目模板。
要点 首次运行 Visual Studio 时,它会提示你获取开发者许可证。有关详细信息,请参阅获取开发者许可证。
- 在 DataModel 文件夹中,打开 SampleDataSource。
在 SampleDataSource 中,添加以下属性和构造函数:
C#public SampleDataCommon() { } private DateTime _pubDate; public DateTime PubDate { get { return this._pubDate; } set { this.SetProperty(ref this._pubDate, value); } }
- 在 SampleDataItem 中,添加以下属性:
C#
public SampleDataItem() { } private String _author; public String Author { get { return this._author; } set { this.SetProperty(ref this._author, value); } } private Uri _link; public Uri Link { get { return this._link; } set { this.SetProperty(ref this._link, value); } }
- 在 SampleDataGroup 中,添加以下构造函数:
C#
public SampleDataGroup() { Items.CollectionChanged += ItemsCollectionChanged; }
- 从 SampleDataSource 的构造函数中删除所有代码。
- 在 SampleDataSource 中,添加以下函数:
C#
private async Task<SampleDataGroup> GetFeedAsync(string feedUriString) { // using Windows.Web.Syndication; SyndicationClient client = new SyndicationClient(); Uri feedUri = new Uri(feedUriString); try { SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri); // This code is executed after RetrieveFeedAsync returns the SyndicationFeed. // Process it and copy the data we want into our FeedData and FeedItem classes. SampleDataGroup feedData = new SampleDataGroup(); feedData.Title = feed.Title.Text; feedData.UniqueId = feed.Id; if (feed.Subtitle != null && feed.Subtitle.Text != null) { feedData.Description = feed.Subtitle.Text; } // Use the date of the latest post as the last updated date. feedData.PubDate = feed.Items[0].PublishedDate.DateTime; foreach (SyndicationItem item in feed.Items) { SampleDataItem feedItem = new SampleDataItem(); feedItem.Title = item.Title.Text; feedItem.UniqueId = item.Id; feedItem.Group = feedData; feedItem.PubDate = item.PublishedDate.DateTime; feedItem.Author = item.Authors[0].Name.ToString(); // Handle the differences between RSS and Atom feeds. if (feed.SourceFormat == SyndicationFormat.Atom10) { feedItem.Content = item.Content.Text; feedItem.Link = new Uri("http://windowsteamblog.com" + item.Id); } else if (feed.SourceFormat == SyndicationFormat.Rss20) { feedItem.Content = item.Summary.Text; feedItem.Link = item.Links[0].Uri; } feedData.Items.Add(feedItem); } return feedData; } catch (Exception) { return null; } } }
- 通过将以下两个使用语句添加到顶部删除不使用的引用:
C#
using Windows.Web.Syndication; using System.Threading.Tasks;
- 将以下方法添加到 SampleDataSource:
C#
public async void SetupData() { await GetFeedsAsync(); } public async Task GetFeedsAsync() { Task<SampleDataGroup> feed1 = GetFeedAsync("http://windowsteamblog.com/windows/b/developers/atom.aspx"); Task<SampleDataGroup> feed2 = GetFeedAsync("http://windowsteamblog.com/windows/b/windowsexperience/atom.aspx"); Task<SampleDataGroup> feed3 = GetFeedAsync("http://windowsteamblog.com/windows/b/extremewindows/atom.aspx"); Task<SampleDataGroup> feed4 = GetFeedAsync("http://windowsteamblog.com/windows/b/business/atom.aspx"); Task<SampleDataGroup> feed5 = GetFeedAsync("http://windowsteamblog.com/windows/b/bloggingwindows/atom.aspx"); Task<SampleDataGroup> feed6 = GetFeedAsync("http://windowsteamblog.com/windows/b/windowssecurity/atom.aspx"); Task<SampleDataGroup> feed7 = GetFeedAsync("http://windowsteamblog.com/windows/b/springboard/atom.aspx"); Task<SampleDataGroup> feed8 = GetFeedAsync("http://windowsteamblog.com/windows/b/windowshomeserver/atom.aspx"); // There is no Atom feed for this blog, so we use the RSS feed. Task<SampleDataGroup> feed9 = GetFeedAsync("http://windowsteamblog.com/windows_live/b/windowslive/rss.aspx"); Task<SampleDataGroup> feed10 = GetFeedAsync("http://windowsteamblog.com/windows_live/b/developer/atom.aspx"); Task<SampleDataGroup> feed11 = GetFeedAsync("http://windowsteamblog.com/ie/b/ie/atom.aspx"); Task<SampleDataGroup> feed12 = GetFeedAsync("http://windowsteamblog.com/windows_phone/b/wpdev/atom.aspx"); Task<SampleDataGroup> feed13 = GetFeedAsync("http://windowsteamblog.com/windows_phone/b/wmdev/atom.aspx"); this._allGroups.Add(await feed1); this._allGroups.Add(await feed2); this._allGroups.Add(await feed3); this._allGroups.Add(await feed4); this._allGroups.Add(await feed5); this._allGroups.Add(await feed6); this._allGroups.Add(await feed7); this._allGroups.Add(await feed8); this._allGroups.Add(await feed9); this._allGroups.Add(await feed10); this._allGroups.Add(await feed11); this._allGroups.Add(await feed12); this._allGroups.Add(await feed13); }
- 通过添加以下代码更新构造函数来加载数据:
C#
public SampleDataSource() { SetupData(); }
- 单击“构建”>“生成解决方案”,或者按 F7 确保生成解决方案且没有错误。
有关以上代码的详细信息,请参阅部分 5:创建博客阅读器(使用 C#/VB 和 XAML 的 Windows 应用商店应用)。若要在 UI 中实现这些更改,请参阅下列部分之一:
- 将示例数据绑定到“拆分应用”模板中的 UI。
- 将示例数据绑定到“网格应用”模板中的 UI。
将示例数据绑定到“拆分应用”模板中的 UI
- 若要在“拆分应用”项目模板中使用示例代码,请打开 ItemsPage.xaml。
- 更改副标题属性以显示发布日期。右键单击 GridView 并打开上下文菜单。 选择“编辑其他模板”>“编辑通用项(ItemTemplate)”>“编辑副本”。
随即将出现一个对话框。 在“名称”字段中,键入:"ItemsPageLandscapeItemTemplate"
- 你将看到一个模板生成并添加到该页。 如果你此时位于模板编辑模式,请在此处单击副标题。 在选中副标题后,单击文本旁的高级属性标记,然后选择“创建数据绑定”。
- 在出现的对话框中,选择 PubDate 并单击“确定”。
- 模板应立即显示以下内容并将位于文件顶部的页面资源中:
C#
<DataTemplate x:Key="ItemsPageLandscapeItemTemplate"> <Grid HorizontalAlignment="Left" Width="250" Height="250"> <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}"> <Image Source="{Binding Image}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/> </Border> <StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}"> <TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/> <TextBlock Text="{Binding PubDate}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/> </StackPanel> </Grid> </DataTemplate
- 双击页面外部,退出模板作用域。
- 为纵向视图和辅视图重复执行该过程。 在“设备”窗格中,单击“辅视图”。 为 ListView 重复执行步骤 3 到步骤 8(此时调用模板 ItemsPageSnappedItemTemplate)。
- 模板应立即显示以下内容并再次位于文件顶部的页面资源中:
C#
<DataTemplate x:Key="ItemsPageSnappedItemTemplate"> <Grid Margin="6"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="60" Height="60"> <Image Source="{Binding Image}" Stretch="UniformToFill"/> </Border> <StackPanel Grid.Column="1" Margin="10,0,0,0"> <TextBlock Text="{Binding Title}" Style="{StaticResource ItemTextStyle}" MaxHeight="40"/> <TextBlock Text="{Binding PubDate}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/> </StackPanel> </Grid> </DataTemplate>
- 在 SplitPage.xaml 中,我们需要进行少数更新。
- 首先我们按以前的方法修复用于 ListView 的 ItemTemplate。
- 右键单击 ListView 并弹出上下文菜单。选择“编辑其他模板”>“编辑通用项(ItemTemplate)”>“编辑副本”。
- 随即将出现一个对话框。在“名称”字段中,键入:ListViewItemTemplate。
- 你将会看到一个模板生成并添加到该页。如果你此时位于模板编辑模式,请在此处单击副标题。在选中副标题后,单击文本旁的高级属性标记,然后选择“创建数据绑定”。在出现的对话框上,选择“作者”并单击“确定”。
- 如果你此时位于模板编辑模式,请单击“描述”。在选中副标题后,单击文本旁的高级属性标记,然后选择“创建数据绑定”。在出现的对话框中,选择 PubDate 并单击“确定”。
- 双击页面外部,退出模板作用域。
- 现在我们需要为纵向和辅视图执行相同的操作。 在“设备”窗格中,单击“辅视图”。 现在为 ListView 执行以上的子步骤(此时将模板命名为 "ListViewItemTemplateSnapped")。
- 若要更新详细信息部分,请单击标题下面的副标题并再次使用数据绑定对话框,绑定到“作者”属性。
- 保存项目并按 F5,调试应用。
可以立即看到页面标题,但是检索源数据时有短暂的延迟。满足所有承诺时,可以在主页看到每个博客。单击其中一个博客,以查看主视图/详细信息视图中的博客文章。
将示例数据绑定到“网格”模板中的 UI
- 若要在“网格应用”模板中使用示例代码,请打开 GroupedItemsPage.xaml。
- 更改副标题属性以显示发布日期。
- 右键单击 GridView 并弹出上下文菜单。 选择“编辑其他模板”>“编辑通用项(ItemTemplate)”>“编辑副本”。
- 随即将出现一个对话框。 在“名称”字段中,键入:GroupedItemsPageLandscapeItemTemplate。
- 你将看到一个模板生成并添加到该页。 如果你此时位于模板编辑模式,请单击副标题。 在选中副标题后,单击文本旁的高级属性标记,然后选择“创建数据绑定”。
- 在出现的对话框中,选择“作者”并单击“确定”。
- 双击页面外部,退出模板作用域。
- 为纵向视图和辅视图重复执行该过程。 在“设备”窗格中,单击“辅视图”。 为 ListView 重复执行步骤 3 到步骤 8(此时调用模板 GroupedItemsPageSnappedItemTemplate)。
- 模板应立即显示以下内容并再次位于文件顶部的页面资源中:
- 在 GroupDetails.xaml 中,我们需要进行少数更新。
- 首先我们按以前的方法修复用于 GridView 的 ItemTemplate。
- 右键单击 ListView。在上下文菜单中,单击“编辑其他模板”>“编辑通用项(ItemTemplate)”>“编辑副本”。
- 随即将出现一个对话框。在“名称”字段中,键入"GridViewItemTemplate"。
- 你将会看到一个模板生成并添加到该页。如果你此时位于模板编辑模式,请单击副标题。在选中副标题后,单击文本旁的高级属性标记,然后选择“创建数据绑定”。在出现的对话框上,选择“作者”并单击“确定”。
- 如果你此时位于模板编辑模式,请单击“描述”。在选中副标题后,单击文本旁的高级属性标记,然后选择“创建数据绑定”。在出现的对话框中,选择 PubDate 并单击“确定”。
- 现在双击页面外部退出模板作用域。
- 为纵向视图和辅视图重复执行这些步骤。 在“设备”窗格中,单击“辅视图”。 现在为 ListView 重复执行以上子步骤(此时将模板命名为 "ListViewItemTemplateSnapped",将描述绑定到作者)。
- 打开 ItemDetailPage.xaml 并查找以下代码行:
C#
<!-- Content is allowed to flow across as many columns as needed --> <common:RichTextColumns x:Name="richTextColumns" Margin="117,0,117,47"> <RichTextBlock x:Name="richTextBlock" Width="560" Style="{StaticResource ItemRichTextStyle}" IsTextSelectionEnabled="False"> <Paragraph> <Run FontSize="26.667" FontWeight="Light" Text="{Binding Title}"/> <LineBreak/> <LineBreak/> <Run FontWeight="Normal" Text="{Binding Subtitle}"/> </Paragraph>
- 在以上代码中将绑定从“副标题”更改为“作者”。
- 保存项目并按 F5,调试应用。
可以立即看到页面标题,但是检索源数据时有短暂的延迟。满足所有承诺时,可以在主页看到每个博客的项。单击组标题以查看组页面,或单击一个项以查看单个博客文章。