张高兴的 UWP 开发笔记:用 Thumb 控件仿制一个可拖动 Button
在 WPF 上可用的控件拖动方法在 UWP 上大多没用,那干脆用 Thumb 仿制一个吧。
关于 Thumb 控件的教程也不多,毕竟在 WPF 控件拖动有很多种方法, Thumb 就显得很鸡肋了。下面我就简单的说说。(MSDN 文档)
不谈什么属性和方法,大多数都是继承的。主要说说 Thumb 的原生事件 DragStarted,DragDelta,DragCompleted。
DragStarted 和字面意思差不多,开始拖动的时候发生的。
DragDelta 拖动进行中,只要你鼠标不放就会一直进行。
DragCompleted 拖动结束后发生。
下面就来仿制一个可以拖动的圆形 Button,像 IPhone 的“小圆点”一样(像下图一样),只不过功能单一,仅仅用来打开 MainPage 里的汉堡菜单。本文仿制 Button 的时候只需要 DragDelta 事件。
实现很简单,我就不写示例了。

我有一个 SplitView “RootSplitView”,作为汉堡菜单的容器。
首先需要在合适的页面敲上一个 <Thumb />,给它个 Name="RootThumb",我是把它放在页面右下角的。
<Thumb Name="RootThumb" Height="55" Width="55" HorizontalAlignment="Right" VerticalAlignment="Bottom" Canvas.ZIndex="101" />
这时设计器右下角应该出现了一个方块,但它不是我需要的圆形,下面打开 Blend 进行样式定制(前面讲 横向ListView 时提过)。默认的 Thumb 样式如下。
<Style x:Key="ThumbStyle1" TargetType="Thumb">
<Setter Property="Background" Value="{ThemeResource ThumbBackground}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="BorderBrush" Value="{ThemeResource ThumbBorderBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundPointerOver"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Background"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundPressed"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Background"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"/>
<Border x:Name="BackgroundPointerOver" BorderBrush="{ThemeResource ThumbBorderBrushPointerOver}" BorderThickness="{TemplateBinding BorderThickness}" Background="{ThemeResource ThumbBackgroundPointerOver}" Opacity="0"/>
<Border x:Name="BackgroundPressed" BorderBrush="{ThemeResource ThumbBorderBrushPressed}" BorderThickness="{TemplateBinding BorderThickness}" Background="{ThemeResource ThumbBackgroundPressed}" Opacity="0"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
因为需要一个圆形并且里面有个汉堡菜单的图标的仿制 Button,我们需要在默认样式提过的 RootGrid 里画个圆,顺便来个 TextBlock 用来显示汉堡菜单的图标。定制好的样式如下。
<Style x:Key="ThumbStyle1" TargetType="Thumb">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="BorderBrush" Value="{ThemeResource ThumbBorderBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Grid x:Name="RootGrid">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundPointerOver"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Background"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundPressed"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Background"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle RadiusY="25" RadiusX="25" Fill="Gray" Opacity="0.6" Stroke="{ThemeResource SystemControlBackgroundAccentBrush}" StrokeThickness="3" />
<TextBlock FontFamily="Segoe MDL2 Assets" Text="" FontSize="22" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Border x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"/>
<Border x:Name="BackgroundPointerOver" BorderBrush="{ThemeResource ThumbBorderBrushPointerOver}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Opacity="0"/>
<Border x:Name="BackgroundPressed" BorderBrush="{ThemeResource ThumbBorderBrushPressed}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Opacity="0"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这时,设计器里应该出现了这个玩意儿(得意~~~)

Button 的 Click 事件怎么实现呢?有 PointerPressed 和 Tapped 两个备选事件。现在的交互事件有三种:Mouse Events(鼠标事件),Touch Events(触摸事件)和 Pointer Events(指针事件),分别为不同的设备提供不同的交互方式。说这么多废话其实直接试试就好了。。。在 Thumb 的 xml 标记里添加 Tapped="RootThumb_Tapped",事件代码如下
private void MainThumb_Tapped(object sender, TappedRoutedEventArgs e)
{
RootSplitView.IsPaneOpen = !RootSplitView.IsPaneOpen;
}
下面说说拖动怎么实现,需要编写 DragDelta 事件。由于 Win10 设备体系庞大,UWP 上谈控件坐标没啥意义,这也正是 WPF 上的控件拖动方案没用的原因。如果你在设计器里像 WinForm 一样拖拽控件设计布局的话,xaml 会给被拖拽的控件一个 Margin,因此 Thumb 的拖拽实现也用的 Margin。首先你需要定义两个 double 私有字段记录 X, Y 轴的位移量。设计目的是 Thumb 在右下角,而页面的坐标零点在左上角,只需要将 Thumb 的 Margin 的 Right,Bottom 给一个位移量的负值即可。完整代码如下。
private void MainThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
// 两个 double 类型,用来记录偏移量
thumbX += e.HorizontalChange;
thumbY += e.VerticalChange; MainThumb.Margin = new Thickness(, , -thumbX, -thumbY);
}
这样,一个圆形的可拖动 Button 就用 Thumb 仿制完成了。
张高兴的 UWP 开发笔记:用 Thumb 控件仿制一个可拖动 Button的更多相关文章
- UWP 用Thumb 控件仿制一个可拖动悬浮 Button
参考了 http://www.cnblogs.com/zhanggaoxing/p/6403430.html,并加以改进. 最终效果::: Thumb 的原生事件 DragStarted,DragDe ...
- 张高兴的 UWP 开发笔记:横向 ListView
ListView 默认的排列方向是纵向 ( Orientation="Vertical" ) ,但如果我们需要横向显示的 ListView 怎么办? Blend for Visua ...
- UWP开发---DIY星级评分控件
一,需求来源 在开发韩剧TV UWP过程中,遇到了星级评分的控件问题,在安卓和html中很容易用现有的轮子实现星级评分,搜索了一下目前UWP还未有相关文章,在WPF的一篇文章中使用Photo shop ...
- 张高兴的 UWP 开发笔记:应用内启动应用 (UWP Launch UWP)
需求:在 A 应用内启动 B 应用,如果 B 应用未安装则跳转应用商店搜索. 启动方式使用 Uri 启动,本文使用尽可能简单,并且能拿来直接用的代码.不涉及启动后的应用数据交互,如需深入了解,请戳 M ...
- 张高兴的 UWP 开发笔记:手机状态栏 StatusBar
UWP 有关应用标题栏 TitleBar 的文章比较多,但介绍 StatusBar 的却没几篇,在这里随便写写.状态栏 StatusBar 用法比较简单,花点心思稍微设计一下,对应用会是个很好的点缀. ...
- 张高兴的 UWP 开发笔记:汉堡菜单进阶
不同于Windows 8应用,Windows 10引入了"汉堡菜单"这一导航模式.说具体点,就拿官方的天气应用来说,左上角三条横杠的图标外加一个SplitView控件组成的这一导航 ...
- 张高兴的 UWP 开发笔记:定制 ContentDialog 样式
我需要一个背景透明的 ContentDialog,像下图一样.如何定制?写了一个简单的示例(https://github.com/ZhangGaoxing/uwp-demo/tree/master/C ...
- 安卓开发笔记——自定义HorizontalScrollView控件(实现QQ5.0侧滑效果)
对于滑动菜单栏SlidingMenu,大家应该都不陌生,在市场上的一些APP应用里经常可以见到,比如人人网,FaceBook等. 前段时间QQ5.0版本出来后也采用了这种设计风格:(下面是效果图) 之 ...
- 葡萄城首席架构师:前端开发与Web表格控件技术解读
讲师:Issam Elbaytam,葡萄城集团全球首席架构师(Chief Software Architect of GrapeCity Global).曾任 Data Dynamics.Inc 创始 ...
随机推荐
- csv和excel的区别
excel 文件只能通过excel打开,里面包含公式或者计算. csv文件是一种通用数据格式,可以用很多方式打开,比如excel.csv 以分割数据,用行分割符号分割行级数据,直接上个例子一目了然. ...
- Laravel邮件发送问题小解
在Laravel中已经有内置了发送邮件的功能,通过 Mail::send 可发送邮件,但要使用这个函数必须先进行相关配置. 在 /app/config/mail.php 中设置你的邮件参数,如下: 1 ...
- matlab find函数
find函数用来获取向量或矩阵中非0元素的索引 假设X是行向量,则find(X)返回的是一个行向量:X'为列向量,find(X')返回的是一个列向量. 看一个例子:A是一个行向量,B是一个列向量,将B ...
- 微软企业库DBBA的研究
Summary:如何入门使用Data Access Application Block,可以参考Enterprise Library 3.1中文帮助:数据访问应用程序块.这篇文章侧重在DAAB工作原理 ...
- Java虚拟机——进度1
Java 虚拟机 一.Java虚拟机的基本结构 ①类加载子系统:从文件系统或者网络中加载Class信息,存放在方法区中. ②方法区中存放放进来的Class信息,也包括一些运行时常量池信息包 ...
- ASCII 码对应表
Macron symbol ASCII CODE 238 : HTML entity : [ Home ][ español ] What is my IP address ? your public ...
- Linux 线程调度与优先级设置
转载:http://blog.csdn.net/a_ran/article/details/43759729 线程调度间的上下文切换 什么是上下文切换? 如果主线程是唯一的线程,那么他基本上不会被调度 ...
- OSG和osgearth显示中文(转载)
osgEarth支持中文过程详解 OSG和osgearth显示中文 一.知识储备 要想很好的理解和解决这个问题,首先要了解什么是多字节和宽字节.说实话我之前也知道这两个字节到底有什么区别,只是简单 ...
- spark连接mongodb
1.添加依赖 hadoop和mongodb的连接器 <dependency> <groupId>org.mongodb.mongo-hadoop</groupId> ...
- Linux下的文件目录结构详解
Linux下的文件目录结构详解 / Linux文件系统的上层根目录 /bin 存放用户可执行的程序 /boot 操作系统启动时所需要的文件 /dev 接口设备文件目录,例如:had表示硬盘 /etc ...