Appbar分为2种:
  • 显示在页面顶部的TopAppBar
  • 显示在页面底部的BottomAppBar
TopAppBar一般用于页面导航,BottomAppBar则用来处理一些用户事件。
本文仅介绍TopAppBar,BottomAppBar会在下一篇文章中进行介绍。
在分析代码之前先上一张程序运行效果图(全屏模式):

TopAppBar
一般来说,TopAppBar是为所有页面服务的。因此只需要创建1个TopAppBar,然后在每个页面调用即可。
创建TopAppbar
1.创建一个基本页面GlobalPage.xaml
这个不用我教你了吧。
注意:在Metro程序中不要创建空白页面。
2.在GlobalPage.xaml里创建1个TopAppbar,并添加几个Button.
[plain] view plaincopyprint?
  1. <Page.TopAppBar>
  2. <AppBar x:Name="globalAppbar" Padding="10,0,10,0" Loaded="OnAppbarLoaded">
  3. <Grid Background="Black">
  4. <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" ScrollViewer.HorizontalScrollBarVisibility="Auto">
  5. <Button x:Name="homeAppbarButton" Style="{StaticResource GlobalPageHomeAppBarButtonStyle}" Click="OnHomeAppbarButtonClicked"></Button>
  6. <Button x:Name="appbarPageAppbarButton" Style="{StaticResource GlobalPageAppBarPageAppBarButtonStyle}" Click="OnAppbarPageAppbarButtonClicked"></Button>
  7. <Button x:Name="localDataPageAppbarButton" Style="{StaticResource GlobalPageLocalDataPageAppBarButtonStyle}" Click="OnLocalDataPageAppbarButtonClicked"></Button>
  8. <Button x:Name="settingPanelPageAppbarButton" Style="{StaticResource GlobalPageSettingPanelPageAppBarButtonStyle}" Click="OnSettingPanelPageAppbarButtonClicked"></Button>
  9. </StackPanel>
  10. </Grid>
  11. </AppBar>
  12. </Page.TopAppBar>
你会注意到Style="{StaticResource GlobalPageHomeAppBarButtonStyle}"。GlobalPageHomeAppBarButtonStyle是什么东东?Button上面的那些”图片“是怎么来的?
故名思义,GlobalPageHomeAppBarButtonStyle只是Button的一种样式而已,你可以在common文件夹下的StandardStyles.xaml里找到很多类型的样式.
为了以后维护方便,我会在一个新的xaml文件定义这些控件的样式(以后也会这样).
创建文件GlobalPageStyle.xaml,在StandardStyles.xaml里找到AppBarButtonStyle,将其复制到GlobalPageStyle.xaml中,并更名为GlobalPageAppBarButtonStyle,然后我们就可以开始修改了!
修改Button基本属性
[plain] view plaincopyprint?
  1. <Setter Property="Foreground" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
  2. <Setter Property="VerticalAlignment" Value="Stretch"/>
  3. <span style="color:#ff0000;"><Setter Property="FontFamily" Value="Segoe UI Symbol"/></span>
  4. <Setter Property="FontWeight" Value="Normal"/>
  5. <span style="color:#ff0000;"><Setter Property="FontSize" Value="40"/></span>
  6. <Setter Property="AutomationProperties.ItemType" Value="App Bar Button"/>

其中字体必须为Segoe UI Symbol.后面会讲到原因。

修改Button基本布局
[plain] view plaincopyprint?
  1. <ControlTemplate TargetType="ButtonBase">
  2. <Grid x:Name="RootGrid" Width="100" Height="100" Margin="10">
  3. <Grid x:Name="BackgroundGrid" Width="100" Height="100" Background="Purple" Opacity=".6"></Grid>
  4. <StackPanel VerticalAlignment="Top" Margin="0,12,0,11" >
  5. <Grid Width="100" Height="50" Margin="0,0,0,5" HorizontalAlignment="Center">
  6. <TextBlock x:Name="BackgroundGlyph" Text="" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0" Foreground="{StaticResource AppBarItemBackgroundThemeBrush}"/>
  7. <ContentPresenter x:Name="Content" HorizontalAlignment="Center" Margin="-1,-1,0,0" VerticalAlignment="Center"/>
  8. </Grid>
  9. <TextBlock
  10. x:Name="TextLabel"
  11. Text="{TemplateBinding AutomationProperties.Name}"
  12. Foreground="{StaticResource AppBarItemForegroundThemeBrush}"
  13. Margin="0,0,2,0"
  14. FontSize="11"
  15. TextAlignment="Center"
  16. Width="88"
  17. MaxHeight="32"
  18. TextTrimming="WordEllipsis"
  19. HorizontalAlignment="Center"
  20. Style="{StaticResource BasicTextStyle}"/>
  21. </StackPanel>
  22. ...
  23. </Grid>
  24. </ControlTemplate>
下面为每一个Button设计不同的样式,以AppBar Button为例
[plain] view plaincopyprint?
  1. <Style x:Key="GlobalPageAppBarPageAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource GlobalPageAppBarButtonStyle}">
  2. <Setter Property="AutomationProperties.AutomationId" Value="GlobalPageAppBarPageAppBarButton"/>
  3. <Setter Property="AutomationProperties.Name" Value="AppBar示例"/>
  4. <Setter Property="Content" Value=""/>
  5. </Style>

可以看到,我们只需要引用之前的基本属性和布局,再根据Button的类型修改和添加相应的属性就可以了。

AutomationProperties.Name 就是Button下方显示的文字。
等一下,Content的Value怎么是空的?上面的那幅"图片"又是什么?
其实上面的"图片"是特殊字符,你可以在字符映射表里找到它们。Value里面的空白部分就是字符的值。
你也可以用类似“”这样的字串来表示。
注意:字体必须为Segoe UI Symbol
至此,TopAppBar就创建完成了。
3.创建全局Frame
在GlobalPage.xaml里创建1个包含Frame的Grid,很简单。
[plain] view plaincopyprint?
  1. <Grid x:Name="rootGrid">
  2. <Frame x:Name="globalFrame"></Frame>
  3. </Grid>

后面就用这个Frame来进行页面的导航。

下面来实现UI逻辑部分
我们程序的主页面是HomePage,GlobalPage只是其中的一个桥梁。
1.当程序从App.xaml.cs启动时,将页面首先定位到GlobalPage
[csharp] view plaincopyprint?
  1. if (!rootFrame.Navigate(typeof(GlobalPage)))
  2. {
  3. throw new Exception("Failed to create initial page");
  4. }

2.加载完GlobalPage页面时,再跳到HomePage。

[csharp] view plaincopyprint?
  1. NavigateToPage(typeof(HomePage), globalFrame);

这样就可以在各个页面调用TopAppBar了.

点击下鼠标右键,看到TopAppBar了吧。
3.下面处理Button事件
很简单,跳转到不同的页面即可。

[csharp] view plaincopyprint?
  1. private void OnSettingPanelPageAppbarButtonClicked(object sender, RoutedEventArgs e)
  2. {
  3. NavigateToPage(typeof(SettingPanelPage));
  4. }
  5. private void NavigateToPage(Type type)
  6. {
  7. NavigateToPage(type, null);
  8. }
  9. private void NavigateToPage(Type type,object obj)
  10. {
  11. globalFrame.Navigate(type, obj);
  12. globalAppbar.IsOpen = false;
  13. }

最后别忘记关闭AppBar.

4.特殊效果
4.1当前页面的对应的按钮不可用
从当前页面跳转到自己本身的行为是没有必要的,因此在显示AppBar的时候将该Button设置为不可用。
你可能会问:Button是在GlobalPage中定义的,我们在HomePage怎样去调用它,况且我怎么知道我现在在哪个页面?
别忘了,TopAppBar是在GlobalPage定义的,并且我们设置了Loaded事件,当TopAppBar加载完毕时,会调用该方法。
我们可以通过GlobalPage中定义的Frame来获取当前页面,并通过当前页面来获取对应的Button。
[csharp] view plaincopyprint?
  1. DisableButton = GetDisableButton(globalFrame.CurrentSourcePageType);
[csharp] view plaincopyprint?
  1. private Button GetDisableButton(Type type)
  2. {
  3. Button button = null;
  4. if(type.Equals(typeof(HomePage)))
  5. {
  6. button = homeAppbarButton;
  7. }
  8. else if (type.Equals(typeof(AppBarPage)))
  9. {
  10. button = appbarPageAppbarButton;
  11. }
  12. else if (type.Equals(typeof(LocalDataPage)))
  13. {
  14. button = localDataPageAppbarButton;
  15. }
  16. else if (type.Equals(typeof(SettingPanelPage)))
  17. {
  18. button = settingPanelPageAppbarButton;
  19. }
  20. return button;
  21. }
不能简单的将该Button设置为不可用,因为下一次在其他页面调出AppBar的时候,该Button就不能用了!
可以所有的Button设置为可用,然后再将该Button设置为不可用。那么怎样去获取所有Button呢?一个一个写?
当然不是。虽然不能直接调用Button,但是我们可以遍历TopAppBar中的元素来找到Button,毕竟Button是在AppBar中定义的。
[csharp] view plaincopyprint?
  1. Grid grid = (sender as AppBar).Content as Grid;
  2. foreach (var element in grid.Children)
  3. {
  4. if (element is StackPanel)
  5. {
  6. StackPanel panel = element as StackPanel;
  7. foreach (var subElement in panel.Children)
  8. {
  9. Button button = subElement as Button;
  10. button.IsEnabled = true;
  11. }
  12. }
  13. }
  14. DisableButton.IsEnabled = false;

OK,完事了。

4.2把鼠标移到Button上时,Button会高亮。
效果图:
很简单,注意到之前Style里中的Opacity=".6"吗?Button默认的透明度为60%,把鼠标移上去的时候将透明度设置为100%就OK啦。
Button基本布局省略的代码片段。
[plain] view plaincopyprint?
  1. <VisualState x:Name="PointerOver">
  2. <Storyboard>
  3. <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGrid" Storyboard.TargetProperty="Opacity">
  4. <DiscreteObjectKeyFrame KeyTime="0" Value="1"/>
  5. </ObjectAnimationUsingKeyFrames>
  6. <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
  7. <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPointerOverForegroundThemeBrush}"/>
  8. </ObjectAnimationUsingKeyFrames>
  9. </Storyboard>
  10. </VisualState>
5.Snap模式处理
Snap模式是什么?我们暂时先不去管它。后面会详细介绍。
调出TopAppBar试着把程序拖到边上,你会发现TopAppBar有一大块没了。
废话,当前窗体就这么大,TopAppBar显示不下了。
针对这种情况,可以让TopAppBar换种风格显示,或者干脆不显示。
对于后者可以在Loaded里加入如下代码
[csharp] view plaincopyprint?
  1. if (ApplicationView.Value == ApplicationViewState.Snapped)
  2. {
  3. globalAppbar.IsOpen = false;
  4. return;
  5. }
呼呼,一个小小的TopAppBar就写了那么多。下篇文章将介绍TopAppBar的兄弟BottomAppBar.

Windows8 Metro开发 (02) : AppBar控件之TopAppBar相关推荐

  1. Windows8 Metro开发 (03) : AppBar控件之BottomAppBar

    BottomAppBar 在介绍BottomAppBar之前还是先上张图. 这次我们关注底部的AppBar. 上图的AppBar分为左右2个部分. 左侧是引用系统自带的AppBar按钮,右侧是自定义的 ...

  2. 【Win 10应用开发】SplitView控件

    [Win 10应用开发]SplitView控件 原文:[Win 10应用开发]SplitView控件 SplitView控件用于呈现分隔视图,简单地说,就是把一个视图分割为两部分,Content属性所 ...

  3. 用友二次开发 用友控件 Js宿主脚本 调用用友T6 登录 参照 控件示例

    用友二次开发 用友控件 Js宿主脚本 调用用友T6 登录 参照 控件示例 /*****************************************, code by 张朋 ' Email: ...

  4. 分享-WinForm界面开发之布局控件WeifenLuo.WinFormsUI.Docking的使用

    分享自伍华聪的-WinForm界面开发之布局控件"WeifenLuo.WinFormsUI.Docking"的使用 本篇介绍Winform程序开发中的布局界面的设计,介绍如何在我的 ...

  5. Qt界面开发(各种控件以及图表)

    Qt界面开发(各种控件以及图表) 1.Qt简洁窗体 源代码链接:点击打开链接 2.QT漂亮界面 源代码链接:点击打开链接 3.音乐播放器界面 源代码链接:点击打开链接 4.六宫格界面 源代码链接:点击 ...

  6. [译][Tkinter 教程02] Message 控件

    已获原作者授权. 原系列地址: Python Tkinter Message 控件 Message 控件用来展示一些文字短消息. Message 和 Label 控件有些类似, 但在展示文字方面比 L ...

  7. firefox扩展开发(八) :控件激活

    firefox扩展开发(八) :控件激活 2008-06-11 17:01 当我们用鼠标点击一个控件,或者用TAB键移动到一个控件上时,我们说这个控件被激活 了(focus),离开这个控件时,我们说这 ...

  8. UG/NX二次开发 选择坐标系控件 UF_UI_specify_csys

    文章作者:里海 来源网站:https://blog.csdn.net/WangPaiFeiXingYuan 简介: UG/NX二次开发 选择坐标系控件 UF_UI_specify_csys 与 老函数 ...

  9. android include 控件详解,Android开发中include控件用法分析

    本文实例讲述了Android开发中include控件用法.分享给大家供大家参考,具体如下: 我们知道,基于Android系统的应用程序的开发,界面设计是非常重要的,它关系着用户体验的好坏.一个好的界面 ...

最新文章

  1. GPT-3开始探索付费使用:每月700块,写得比莎士比亚还多
  2. php 清除之前echo_PHP入门读书笔记(三): 常量和变量
  3. git使用-设置项目忽略文件
  4. Java对异常处理或抛出之后,后面代码会不会再执行?
  5. zynqpl端时钟_第十二章 ZYNQ-MIZ702 PS读写PL端BRAM
  6. spring的事物配置
  7. 在Perl程序中显示进度条之多姿多彩的自写代码
  8. 通用滤波器设计----东南大学的
  9. windosw7 Hosts文件的位置
  10. 六一特辑丨“我的礼物我开发”这群小朋友在用新的方式对话未来
  11. 一览众山小的上一句是什么,怎么理解一览众山小的意思?
  12. HDU-2502 月之数 组合数
  13. 曼昆《经济学原理宏观》读书笔记
  14. IAR Embedded Workbench IDE 显示行号
  15. JavaScript如何获取css属性
  16. 某班的成绩出来了,现在老师要把班级的成绩打印出来,和 显示当前时间
  17. [转载] vim风格设置
  18. DiskGeniux无损分区
  19. vnc以及xfce安装\xrdp连接
  20. 全国计算机一级选择题免费,全国计算机一级考试选择题试题与详细答案

热门文章

  1. 【Groovy】map 集合 ( map 集合定义 | 通过 getClass 函数获取 map 集合的类型 | 代码示例 )
  2. 【Windows 逆向】OD 调试器工具 ( OD 调试数据时硬件断点对应的关键代码 | 删除硬件端点恢复运行 )
  3. 【Android 逆向】IDA 工具使用 ( 十六进制视图 Hex View-1 | 结构体视图 Structures | 枚举视图 Enums | 导入视图 Import | 导出视图 )
  4. 【Android 插件化】插件化技术弊端 ( 恶意插件化程序的解决方向 | 常用的插件化虚拟引擎 )
  5. 【FFmpeg】FFmpeg 帮助文档使用
  6. 【Android 进程保活】应用进程拉活 ( 账户同步拉活 | 账号添加 | 源码资源 )
  7. 【Android 系统开发】Android JNI 之 JNIEnv 解析
  8. Cocos2d-x3.0 不规则Button
  9. js获取浏览器宽度和高度值
  10. 梳理一下我理解的aop