Win10 UWP开发系列:开发一个自定义控件——带数字徽章的AppBarButton
最近有个项目有一个这样的需求,在文章浏览页底部有几个AppBarButton,其中有一个是评论按钮,需要在评论按钮上显示一个红色数字,类似微信的新消息提醒:
这种设计在iOS和Android平台都是很常见的,但UWP上并没有提供现成的控件。所以只能自己实现一个了。
做出来效果是这样的:
分析一下实现的思路。首先这还是一个AppBarButton,只是其中增加了一个数字徽章的显示,这个属性应该是可以绑定到其他属性的,如果绑定的值不为0,则显示数字,如果为0则隐藏数字。因此我们可以通过继承AppBarButton,并修改其模板来实现这个控件。
下面动手实践一下吧。我已经安装了最新的VS2017,不过使用VS2015的话也是差不多的。首先创建一个名为AppBarBadgeButtonSample的UWP项目:
选择在Blend中打开:
在页面上添加一个AppBar:
添加后是这样的结构:
然后需要将默认AppBarButton的模板导出来,给我们自定义的控件用。在按钮上右键选择编辑模板,编辑副本:
输入一个名字,为了简单起见我们就在当前文件中创建这个样式好了,点击确定。
切换到XAML模式,可以看到页面的XAML代码中添加了这样的资源:
这个就是AppBarButton的控件模板了。我们需要在这个默认模板的基础上,实现自定义的AppBarBadgeButton。
现在返回到VS2017,在当前项目中添加一个名为Controls的文件夹,再添加一个名为AppBarBadgeButton的文件夹,然后添加一个模板控件:
确定后,可以看到项目中添加了两个文件,一个是cs文件,一个是一个xaml文件:
这个Generic.xaml即控件的模板,但是如果每个控件的模板都写在这里的话,会显得比较乱。最好是每个控件的cs文件和xaml文件都放在一块。所以在AppBarBadgeButton目录下添加一个名为AppBarBadgeButton.xaml的样式文件,这样方便管理。同时把控件的命名空间从AppBarBadgeButtonSample.Controls.AppBarBadgeButton改为AppBarBadgeButtonSample.Controls。
现在可以把之前生成的默认的AppBarButton的模板复制过来了:
注意,要把key删掉,TargetType都要改成AppBarBadgeButton:
现在需要把这个模板导入到Generic.xaml中,把Generic.xaml中自动生成的删掉,改为下面这样:
- <ResourceDictionary.MergedDictionaries>
- <ResourceDictionary Source="ms-appx:///Controls/AppBarBadgeButton/AppBarBadgeButton.xaml" />
- </ResourceDictionary.MergedDictionaries>
这样所有的控件的模板都跟自己的cs文件放在一块,Generic.xaml文件中只放引用位置,项目结构就清晰多了。
现在回到AppBarBadgeButton.cs,把控件的基类从Control改成AppBarButton。这样控件的所有行为都和默认的AppBarButton一致了。
我们需要一个数字属性,和一个控制数字是否可见的属性。添加以下代码:
- public string Count
- {
- get { return (string)GetValue(CountProperty); }
- set { SetValue(CountProperty, value); }
- }
- // Using a DependencyProperty as the backing store for Count. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty CountProperty =
- DependencyProperty.Register("Count", typeof(string), typeof(AppBarBadgeButton), new PropertyMetadata("0", null));
这是一个依赖属性。注意为什么数字的类型是string呢?为什么不设置成int?
卖个关子,先做完再说。
现在可以修改控件的模板了。仔细分析模板就能找到需要改的地方,有一个名为ContentRoot的Grid,应该就是这里了,在名为Content的ContentPresenter后面添加一个Border和一个TextBlock来显示数字:
- <Border CornerRadius="8" Margin="8" HorizontalAlignment="Right" VerticalAlignment="Top"
- Background="Red" Grid.Row="0" MinWidth="16" Height="16">
- <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
- FontSize="10" Text="{TemplateBinding Count}" Foreground="Yellow" />
- </Border>
注意,这里要使用TemplateBinding将文本绑定到Count属性。
现在来试试。我们设置Page的x:Name为rootPage,把刚才在主页面添加的AppBarButton改成自定义的AppBarBadgeButton,不要忘了引入命名空间:xmlns:localControls="using:AppBarBadgeButtonSample.Controls"
再设置Page的DataContext,并添加一个Count属性,把AppBarBadgeButton的Count绑定到cs文件的Count属性上:
xaml:
- <Page
- x:Class="AppBarBadgeButtonSample.MainPage"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:local="using:AppBarBadgeButtonSample"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:localControls="using:AppBarBadgeButtonSample.Controls"
- mc:Ignorable="d"
- x:Name="rootPage">
- <Page.BottomAppBar>
- <CommandBar>
- <CommandBar.Content>
- <Grid/>
- </CommandBar.Content>
- <localControls:AppBarBadgeButton Icon="Accept" Count="{Binding Count}" Label="AppBarButton"/>
- <AppBarButton Icon="Cancel" Label="AppBarButton"/>
- </CommandBar>
- </Page.BottomAppBar>
- <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
- </Grid>
- </Page>
cs:
- public sealed partial class MainPage : Page
- {
- public MainPage()
- {
- this.InitializeComponent();
- this.Count = ;
- this.rootPage.DataContext = this;
- }
- public int Count { get; set; }
- }
我这里没有用标准的MVVM,只是简单演示一下。现在运行下看看:
效果出来了。
现在思考刚才提到的问题,为什么在DataContext里的属性可以设置为int,而控件本身的依赖属性必须设置为string呢?如果有兴趣可以将依赖属性改为int试试,结果就是按钮上什么也显示不出来:
这是因为,在使用TemplateBinding的时候,必须保证source属性和target属性的值的类型是匹配的,TextBlock的Text属性是string,那么用于绑定的属性的类型也必须是string。在使用TemplateBinding时,没有机会进行自动的类型转换。如果类型不匹配,则无法绑定。可参考:https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/templatebinding-markup-extension
现在可以显示数字了,但是还需要做的更完善一点。有数字的时候显示,如果为0的时候就隐藏掉。所以再做一点小小的工作:
添加一个控制是否显示数字的属性:
- public Visibility BadgeVisibility
- {
- get { return (Visibility)GetValue(BadgeVisibilityProperty); }
- set { SetValue(BadgeVisibilityProperty, value); }
- }
- // Using a DependencyProperty as the backing store for BadgeVisibility. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty BadgeVisibilityProperty =
- DependencyProperty.Register("BadgeVisibility", typeof(Visibility), typeof(AppBarBadgeButton), new PropertyMetadata(Visibility.Collapsed, null));
当Count值变化时,将其设置为隐藏:
- public string Count
- {
- get { return (string)GetValue(CountProperty); }
- set { SetValue(CountProperty, value); }
- }
- // Using a DependencyProperty as the backing store for Count. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty CountProperty =
- DependencyProperty.Register("Count", typeof(string), typeof(AppBarBadgeButton), new PropertyMetadata("", OnCountChanged));
- private static void OnCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- int count = ;
- int.TryParse(e.NewValue.ToString(), out count);
- if (count != )
- {
- ((AppBarBadgeButton)d).SetValue(BadgeVisibilityProperty, Visibility.Visible);
- }
- else
- {
- ((AppBarBadgeButton)d).SetValue(BadgeVisibilityProperty, Visibility.Collapsed);
- }
- }
最后将数字的Visibility属性绑定到这个值上:
- <Border CornerRadius="8" Margin="8" HorizontalAlignment="Right" VerticalAlignment="Top"
- Background="Red" Visibility="{TemplateBinding BadgeVisibility}" Grid.Row="0" MinWidth="16" Height="16">
代码已开源:https://github.com/yanxiaodi/UWP-AppBarBadgeButton
Win10 UWP开发系列:开发一个自定义控件——带数字徽章的AppBarButton的更多相关文章
- Office365开发系列——开发一个全功能的Word Add-In
2016年10月我参加了在北京举行的DevDays Asia 2016 - Office 365应用开发”48小时黑客马拉松“,我开发的一个Word Add-In Demo——WordTemplate ...
- Android开发系列之创建自定义控件
Android开发过程中我们经常需要定义自己的控件,一方面基于复用的角度考虑,一方面也是基于逻辑处理思维的角度考虑.在这篇博客里面,笔者想要介绍.总结几种Android自定义控件的方法,如果有什么不对 ...
- win10 UWP 申请微软开发人员
申请微软开发人员能够到https://dev.windows.com/zh-cn/programs/join 假设是学生,先去http://www.dreamspark.com/ 假设是英文,点stu ...
- [ Office 365 开发系列 ] 开发模式分析
前言 本文完全原创,转载请说明出处,希望对大家有用. 在正式开发Office 365应用前,我们先了解一下Office 365的开发模式,根据不同的应用场景,我们选择最适合的开发模式. 阅读目录 Of ...
- win10 uwp 在 Canvas 放一个超过大小的元素会不会被裁剪
我尝试在一个宽度200高度200的 Canvas 放了一个宽度 300 高度 300 的元素,这个元素会不会被 Canvas 裁剪了? 经过我的测试,发现默认是不会被裁剪 火火问了我一个问题,如果有一 ...
- [ Office 365 开发系列 ] Graph Service
前言 本文完全原创,转载请说明出处,希望对大家有用. 通过[ Office 365 开发系列 ] 开发模式分析和[ Office 365 开发系列 ] 身份认证两篇内容的了解,我们可以开始使用Offi ...
- Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App
安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...
- Win10 UWP开发系列:实现Master/Detail布局
在开发XX新闻的过程中,UI部分使用了Master/Detail(大纲/细节)布局样式.Win10系统中的邮件App就是这种样式,左侧一个列表,右侧是详情页面.关于这种 样式的说明可参看MSDN文档: ...
- Win 10 UWP开发系列:设置AppBarButton的图标
在WP8以前,页面最下面的四个小圆按钮是不支持绑定的,WP8.1 RT之后,系统按钮升级成了AppBarButton,并且支持绑定了.在Win10 UWP开发中,按钮的样式发生了变化,外面的圆圈没有了 ...
随机推荐
- [CSS3] 学习笔记-CSS定位
页面的设计需要通过摆放不同的模块在不同的位置,这个时候需要使用到定位和浮动的知识点,CSS3定位功能是很强大的,利用它你可以做出各种各样的网络布局. 1.CSS定位 1)定位机制 普通流:元素按照其在 ...
- JavaScript从作用域到闭包
目录 作用域 全局作用域和局部作用域 块作用域与函数作用域 作用域中的声明提前 作用域链 函数声明与赋值 声明式函数.赋值式函数与匿名函数 代码块 自执行函数 闭包 作用域(scope) 全局作用域 ...
- 笑谈ArcToolbox (2) 开启ArcToolbox的钥匙
笑谈ArcToolbox (2) 开启ArcToolbox的钥匙 by 李远祥 GIS人遇到ArcToolbox就像找到了宝藏一样兴奋,但并不是每个找到宝藏的人都具备开启宝藏的钥匙.有时候功能强大并不 ...
- synchronized的使用及注意事项
主要来源:http://blog.csdn.net/luoweifu/article/details/46613015 1.synchronized(this) void method(){ sync ...
- vue路由表(简单)
import Vue from 'vue'import VueRouter from 'vue-router'Vue.use(VueRouter) const first = { template: ...
- qppium 原理解析
Appium是 c/s模式的appium是基于 webdriver 协议添加对移动设备自化api扩展而成的webdriver 是基于 http协议的,第一连接会建立个 session 会话,并通过 p ...
- mac os x在PC上安装
系统安装之前的准备工作及安装过程简介 前面我们已经提到,苹果电脑虽然已经采用了x86架构的Intel处理器,但其官方并不提供在非苹果电脑上安装Mac OS的支持.所以,要想在普通PC/笔记本电脑上安装 ...
- Android 7.0 PopupWindow 的兼容问题
Android7.0 PopupWindow的兼容问题 Android7.0 中对 PopupWindow 这个常用的控件又做了一些改动,修复了以前遗留的一些问题的同时貌似又引入了一些问题,本文 ...
- awk,sed文本处理案例
#!/bin/bash ############################################################################# #针对一个多级目录下 ...
- 最新虚拟机SAP ECC6.0 EHP7带示例数据IDES版+BW740
学习SAP,需要虚拟机,请联系QQ:858-048-581 版本:ECC6.0 EHP7.虚拟机操作系统:windows server 2008 64bit..数据库:SQL2008 R2.系统已经做 ...