我们紧接着上篇,开始我们的Metro风格应用开发。

-----------------------------------我是华丽的分割线-----------------------------------------

17.添加页面和导航
   a)为了使我们的博客阅读器能够适用于所有的博客,我们必须向应用添加更多的页面并处理如何在这些页面之间进行导航。
     首先,我们需要一个能够列出所有博客的页面。当阅读器从该页面中选择某个博客时,我们将加载该博客的文章列表。
     我们已创建的分页阅读器也可以完成此功能,但我们希望对它做一点改进。最后,我们需要添加一个详细信息页面,
     以便阅读单个博客文章,而不至于让列表视图占用空间。
   b)页面模板
     我们不需要从空白模板开始创建每个页面。Visual Studio 12 附带了一个页面模板的集合,
     这些模板对于各种情形都很有用。以下是可用的页面模板。
        页面类型 描述
      组详细信息页 显示单个组的详细信息以及组中每个项目的预览。
      分组项页 显示分组的集合。
      项详细信息页 详细显示一个项目,并允许导航到相邻的项目。
      项页 显示项目的集合。
      拆分页 显示项目的列表以及所选项目的详细信息。
      基本页 可以适应不同方向和视图的空白页面,并且包含一个标题和返回按钮。
      空白页 用于 Metro 风格应用的空白页面。
   c)向应用添加页面。
      选择“项目”>“添加新项”。“添加新项”对话框即会打开。
      在“已安装”窗格中,展开“Visual C#”或“Visual Basic”。
      选择“Windows Metro 风格”模板类型。
      在中心窗格中,选择要添加到项目中的页面类型。
      为该页面输入名称ItemsPage。
      单击“添加”。XAML 和你的页面的代码隐藏文件即被添加到项目中。
      如图:

弹出提示,选择"是",如图:

     针对我们的博客阅读器,我们将添加一个项目页面来显示所有博客的列表。我们将此页面命名为 ItemsPage。
     我们添加一个拆分页面来显示每个博客的文章。我们将此页面命名为 SplitPage。
     拆分页面模板与我们为简单博客阅读器应用创建的页面相似,但更加精炼。我们针对详细信息页面
     (将其命名为 DetailPage)使用基本页面模板。它只有返回按钮、页面标题和一个用于显示文章内容的 WebView 控件。
     但并不是像我们在拆分页面中那样将来自 HTML 字符串的文章内容加载到 WebView,
     我们导航到文章的 URL 并显示实际的 Web 页面。
  d)模板页面全部从 LayoutAwarePage 类派生而来,默认情况下,这些模板页面能够比我们使用的初始 
     MainPage执行更多的功能。LayoutAwarePage 是 Page 的一个实现,为 Metro 风格应用开发启用了重要的功能:
     应用程序视图状态到视觉状态的映射使页面能够适应不同的分辨率、方向和视图。
     GoBack 和 GoHome 事件处理程序支持基本的导航。默认的视图模型为你提供了一个简单的可绑定数据源。
     页面模板还使用 StandardStyles.xaml 中的样式和模板,这些样式和模板应用 Metro 风格应用的设计指南。
     我们将使用其中一些样式作为开始,并修改它们的副本来自定义应用的外观。

18.在页面之间导航
   XAMLUI 框架提供了使用 Frame 和 Page 的内置导航模型,其工作方式与在 Web 浏览器中的导航方式非常相似。
   Frame控件可托管 Page,并且具有导航历史记录,你可以通过该历史记录在访问过的页面中前进和后退。
   在导航时,你可以在页面之间传递数据。在 Visual Studio 项目模板中,名为 rootFrame 的 Frame 被设置为应用窗口的内容。
   我们来看看 App.xaml.cs中的代码:

View Code

 /// <summary>/// Invoked when the application is launched normally by the end user.  Other entry points/// will be used when the application is launched to open a specific file, to display/// search results, and so forth./// </summary>/// <param name="args">Details about the launch request and process.</param>protected override void OnLaunched(LaunchActivatedEventArgs args){// Do not repeat app initialization when already running, just ensure that// the window is activeif (args.PreviousExecutionState == ApplicationExecutionState.Running){Window.Current.Activate();return;}if (args.PreviousExecutionState == ApplicationExecutionState.Terminated){//TODO: Load state from previously suspended application
            }// Create a Frame to act navigation context and navigate to the first pagevar rootFrame = new Frame();if (!rootFrame.Navigate(typeof(MainPage))){throw new Exception("Failed to create initial page");}// Place the frame in the current Window and ensure that it is activeWindow.Current.Content = rootFrame;Window.Current.Activate();}

   这些代码用于创建框架,将其设置为 Window 的内容,并导航到 MainPage。由于我们的完整应用的首页是 ItemsPage,
   因此我们将调用更改为导航方法并在此处所示的 ItemsPage 中进行传递。修改的代码如下:

    // Create a Frame to act navigation context and navigate to the first pagevar rootFrame = new Frame();if (!rootFrame.Navigate(typeof(ItemsPage))){throw new Exception("Failed to create initial page");}

  加载 ItemsPage 时,我们需要获得数据源的一个实例,并检索要显示的源数据,
   就像我们在使用应用中的数据部分中使用 MainPage 一样。我们将代码置于页面模板中包括的 OnNavigatedTo 方法替代中,
   如果尚未检索源,我们将调用 FeedDataSource.GetFeedsAsync 方法。以下是 ItemsPage.xaml.cs代码:

  protected override async void OnNavigatedTo(NavigationEventArgs e){FeedDataSource feedDataSource = App.DataSource;if (feedDataSource.Feeds.Count == 0){await feedDataSource.GetFeedsAsync();}DefaultViewModel["Items"] = feedDataSource.Feeds;}

  当用户从集合中选取博客时,我们从项目页导航到拆分页。为了执行此导航,我们希望 GridView 项目响应单击(如按钮)操作,
   而不是被选定。为了使 GridView 项目可单击,我们按如下所示设置 SelectionMode 和 IsItemClickEnabled 属性。
   然后我们为 GridView 的 ItemClick 事件添加一个事件处理程序。以下是 ItemsPage.xaml 中用于 GridView 的 XAML,其中已设置属性,
   并已添加 ItemClick 事件。
   项目页面还包含一个名为 itemListView 的列表视图,如果“调整”了应用,则会显示该列表视图来代替网格。
   我们将在适应不同的布局部分中对此进行更详细的讨论。目前,我们只需对 ListView 进行与对 GridView 所做更改相同的更改,
   以确保它们的行为相同。整个Xaml代码如下:

View Code

  <!-- 在大多数视图状态中使用的水平滚动网格--><GridViewx:Name="itemGridView"AutomationProperties.AutomationId="ItemsGridView"AutomationProperties.Name="Items"TabIndex="1"Grid.Row="1"Margin="0,-4,0,0"Padding="116,0,116,46"ItemsSource="{Binding Source={StaticResource itemsViewSource}}"ItemTemplate="{StaticResource Standard250x250ItemTemplate}"SelectionMode="None"IsItemClickEnabled="True"ItemClick="itemView_ItemClick"/><!-- 垂直滚动列表仅在对齐后使用--><ListViewx:Name="itemListView"AutomationProperties.AutomationId="ItemsListView"AutomationProperties.Name="Items"TabIndex="1"Grid.Row="1"Visibility="Collapsed"Margin="0,-10,0,0"Padding="10,0,0,60"ItemsSource="{Binding Source={StaticResource itemsViewSource}}"ItemTemplate="{StaticResource Standard80ItemTemplate}"SelectionMode="None"IsItemClickEnabled="True"ItemClick="itemView_ItemClick"/>

  itemView_ItemClick事件如下:

View Code

    private void itemView_ItemClick(object sender, ItemClickEventArgs e){// Navigate to the split page, configuring the new page// by passing the clicked item (FeedItem) as a navigation parameterthis.Frame.Navigate(typeof(SplitPage), e.ClickedItem);}

  若要在页面之间导航,你可以使用 Frame 控件的 Navigate、GoForward 和 GoBack 方法。
   通过 Navigate(TypeName, Object) 方法可以导航并将数据对象传递到新页面。我们将使用此方法在我们的页面之间传递数据。
   第一个参数 typeof(MainPage) 是我们将要导航到的页面的 Type。第二个参数是我们传递给将要导航到的页面的数据对象。
   在本例中,我们传递 clicked 项。在 SplitPage.xaml.cs代码隐藏页面中,
   我们需要使用刚刚从项目页面传递的 FeedData 对象执行某些操作。为此,我们将覆盖Page的OnNavigatedTo方法。
   该方法已添加到页面模板代码中,因此我们只需要对其进行修改以便与我们的数据关联。
   模板页面包含一个名为 DefaultViewModel 的内置视图模型,我们可以将数据与之关联。
   NavigationEventArgs.Parameter 属性包含从项目页面传递的数据对象。 我们将其转换回 FeedData 对象,
   并将信息提要数据添加至具有关键字 Feed 的 DefaultViewModel,
   将 FeedData.Items 属性添加至具有关键字 Items 的 DefaultViewModel。以下是更新的 OnNavigatedTo 方法:

protected override void OnNavigatedTo(NavigationEventArgs e){// TODO: Assign a bindable group to this.DefaultViewModel["Group"]// TODO: Assign a collection of bindable items to this.DefaultViewModel["Items"]FeedData feedData = e.Parameter as FeedData;if (feedData!=null){DefaultViewModel["Feed"] = feedData;DefaultViewModel["Items"] = feedData.Items;if (!UsingLogicalPageNavigation()){itemsViewSource.View.MoveCurrentToFirst();}}}

  在 Visual Studio 页面模板中,TODO 注释表示我们从何处将我们的数据对象添加至具有关键字 Group 的 DefaultViewModel。
   由于我们使用的是关键字 Feed,因此我们需要更改页面标题中的绑定,以绑定到 Feed 属性,而不是 Group。
   在 SplitPage.xaml 中,更改名为 pageTitle 的 TextBlock 的 Text 绑定以绑定到 Feed.Title,
   如下所示: <TextBlock x:Name="pageTitle" Grid.Column="1" Text="{Binding Feed.Title}" Style="{StaticResource PageHeaderTextStyle}"/>

  要导航回项目页面,Visual Studio 页面模板包含相应的代码来处理 BackButton 的 Click 事件,并调用 Frame.GoBack 方法。
   我们需要再做一些更改才能完成向我们添加到组中的新页面添加功能的操作。将这些代码添加到应用中后,
   我们便可以继续对我们的应用进行风格和动画设置。
   在 ItemsPage.xaml 中,页面标题绑定到具有关键字 AppName 的静态资源。将此资源中的文本更新到博客中,如下所示。
     <x:String x:Key="AppName">Refactor's Blog</x:String>

  更新SplitPage.xaml 中,将名为 titlePanel 的网格更改为跨 2 个列,Xaml代码如下:

View Code

   <!-- 后退按钮和页标题--><Grid x:Name="titlePanel" Grid.ColumnSpan="2"><Grid.ColumnDefinitions><ColumnDefinition Width="Auto"/><ColumnDefinition Width="*"/></Grid.ColumnDefinitions><Buttonx:Name="backButton"Click="GoBack"IsEnabled="{Binding DefaultViewModel.CanGoBack, ElementName=pageRoot}"Style="{StaticResource BackButtonStyle}"/><TextBlock x:Name="pageTitle" Grid.Column="1" Text="{Binding Feed.Title}" Style="{StaticResource PageHeaderTextStyle}"/></Grid>

   同样在 SplitPage.xaml 中,我们需要更改用来显示所选博客文章的标题和内容的布局。Xaml代码如下:

View Code

  <!-- 选定项的详细信息--><ScrollViewerx:Name="itemDetail"AutomationProperties.AutomationId="ItemDetailScrollViewer"Grid.Column="1"Grid.Row="1"Padding="70,0,120,0"DataContext="{Binding SelectedItem, ElementName=itemListView}"Style="{StaticResource VerticalScrollViewerStyle}"><Grid x:Name="itemDetailGrid" ><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions><TextBlock x:Name="itemTitle" Margin="0,-10,0,0" Text="{Binding Title}" Style="{StaticResource SubheaderTextStyle}"/><Border x:Name="contentViewBorder" BorderBrush="Gray" BorderThickness="2" Grid.Row="1" Margin="0,15,0,20"><Grid><WebView x:Name="contentView" /><Rectangle x:Name="contentViewRect" /></Grid></Border></Grid></ScrollViewer>

   在 SplitPage.xaml.cs 中,向 ItemListView_SelectionChanged 事件处理程序添加代码,
   使用所选博客文章的内容填充 WebView,代码如下:

View Code

  private void itemView_ItemClick(object sender, ItemClickEventArgs e){// Navigate to the split page, configuring the new page// by passing the clicked item (FeedItem) as a navigation parameterthis.Frame.Navigate(typeof(SplitPage), e.ClickedItem);}

  在 DetailPage.xaml 中,我们需要将标题文本绑定到博客文章标题,并添加一个 WebView 控件以显示博客页面。
   Xaml代码如下:

View Code

    <!-- 后退按钮和页标题--><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 Title}" Style="{StaticResource PageHeaderTextStyle}" Grid.Column="1"/><Border x:Name="contentViewBorder" BorderBrush="Gray" BorderThickness="2" Grid.Row="1" Margin="120,15,20,20"><WebView x:Name="contentView" /></Border></Grid>

  在 DetailPage.xaml.cs 中,将代码添加到 OnNavigatedTo 方法中,代码如下:  

View Code

protected override void OnNavigatedTo(NavigationEventArgs e){// Add this code to navigate the web view to the selected blog post.FeedItem feedItem = e.Parameter as FeedItem;if (feedItem != null){this.contentView.Navigate(feedItem.Link);this.DataContext = feedItem;}}

19.以上操作基本完成,为了能使程序正常运行,请按如下操作:

  a)注意注释掉LayoutAwarePage中的OnNavigatedFrom方法:
         protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            /*var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
            var pageState = new Dictionary<String, Object>();
            this.SaveState(pageState);
            frameState[_pageKey] = pageState;*/
        }
  
   b)更改StandardStyles.xaml文件中键值为VerticalScrollViewerStyle的属性:
       <Style x:Key="VerticalScrollViewerStyle" TargetType="ScrollViewer">
          <Setter Property="HorizontalScrollBarVisibility" Value="Auto"/>
          <Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
          <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Auto"/>
          <Setter Property="ScrollViewer.VerticalScrollMode" Value="Enabled"/>
          <Setter Property="ScrollViewer.ZoomMode" Value="Disabled"/>
      </Style>
 
   c)Standard250x250ItemTemplate的属性:
       <!-- 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="../Assets/myLogo.jpg" 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>

20.程序截图:

点击其中一个转到下一个页面,如图:

未完待续,敬请期待....

使用Windows8开发Metro风格应用五相关推荐

  1. 使用Windows8开发Metro风格应用三

    我们紧接着上篇,开始我们的Metro风格应用开发. -----------------------------------我是华丽的分割线------------------------------- ...

  2. 使用Windows8开发Metro风格应用四

    我们紧接着上篇,开始我们的Metro风格应用开发. -----------------------------------我是华丽的分割线------------------------------- ...

  3. 使用 C++ 创建你的第一个 Metro 风格应用

    WindowsMetro 风格应用专门针对 Windows 8 Consumer Preview 所提供的用户体验量身定制.每个出色的 Metro 风格应用都遵循特定的设计准则,这使得此类应用与传统的 ...

  4. Windows8开发指南(16)开发基于Windows8的第一个metro界面C++程序

    微软公布了Windows8开发人员预览版, http://msdn.microsoft.com/en-us/windows/home?ocid=ban-f-cn-dca-Sep-Win8Build 大 ...

  5. 【windows8开发】开发平台与开发框架

    开门见山,先把windows8 开发平台和开发框架分享给大家.       win8 App开发主要分成两部分,desktop app和metro app.右边蓝色的部分就是desktop app的部 ...

  6. 【Windows8开发】关于WinRT组件,WinRT dll,Win32 dll,WinRT exe组件的一些尝试

    随着Win8的推出,提出了很多新的概念,比如WinRT Component,WinRT dll,WinRT exe component等.基于这些新的概念,进行了很多尝试,本文会把结果分享给大家,希望 ...

  7. android+metro风格,Metro、iOS、Android之三大UI风格对比

    三种移动平台,三种风格迥异的UI界面.先有iOS,后有Android,但是Metro UI的风格,早在许久之前就深入现代设计殿堂. 图:Metro UI(左).iOS UI(中).Android UI ...

  8. 超棒的微软Metro风格Logo设计

    日期:2013-2-12  来源:GBin1.com Metro风格是今年的一大设计趋势之一,在今天这篇文章中我们收集了一套超棒的Metro风格Logo设计,如果你在开发或者设计一套metro风格的网 ...

  9. WP7上Metro风格的程序栏图标汇总

    在开发一款WP7程序时,应用程序图标是我们不可或缺的资源.轩辕在这里对网上的大部分Metro风格的应用程序栏图标进行了总结,希望可以给园子里面的各位有点帮助. 1. 其实Microsoft Visua ...

最新文章

  1. 人工智能和大数据的开发过程中需要注意这12点
  2. vscode个人配置
  3. Void void Void用在泛型
  4. 【Android 应用开发】Google 官方 EasyPermissions 权限申请库 ( 完整代码示例 | 申请权限 | 申请权限原理对话框 | 引导用户手动设置权限对话框 )
  5. [JSOI2008]火星人
  6. Java 技术篇 - 启动web服务接收浏览器请求并响应实例演示,解决socket响应浏览器显示中文乱码问题,web服务response响应设置浏览器显示字体方法
  7. CF #737(div2)C. Moamen and XOR 与和异或-找规律
  8. java费波拉切_面试题 - 不再犯错 - 博客园
  9. halcon使用直线标定板,标定相机内参代码
  10. 延边大学c语言题库,延边大学-SPOC官方网站
  11. 开源管理系统OSSIM设置 语言为中文简体
  12. Bailian4151 电影节【贪心】
  13. 洛谷 P1840 【Color the Axis_NOI导刊2011提高(05)】 题解
  14. 使用 kotlin 开发 android 遇到的问题
  15. MongoDB——客户端Robo 3T v1.4.3 安装
  16. 魔兽争霸III背景渊源
  17. 成都传智播客,学生老师共同举杯庆祝初战高胜!
  18. 使用小程序制作一个飞机大战小游戏
  19. [SCOI2009]粉刷匠 DP)
  20. springboot根据cron获取任务执行上次和下次执行时间

热门文章

  1. 电脑刚开机显示正在锁定计算机在怎么回事,电脑开机一直停留在诊断自动修复界面怎么回事...
  2. 领扣 LeetCode 42:接雨水(java)(网易有道面试真题)
  3. 【企业管理】价值创造的文化支撑
  4. 信息系统项目管理师论文考试汇总(2010~2021年)
  5. BaseAction
  6. 笔记-项目质量管理-过程决策程序图法
  7. Java中将String格式的标准时间字符串转换为Date格式的方法
  8. 解决pip使用异常No module named 'pip'
  9. Winform中实现ZedGraph不显示y=0这条刻度线
  10. SpringBoot中将thymeleaf升级到3.0或以上版本