Extensions in UWP Community Toolkit - Mouse Cursor
概述
UWP Community Toolkit Extensions 中有一个为 Mouse 提供的扩展 - Mouse Cursor Extensions,本篇我们结合代码详细讲解 Mouse Cursor Extensions 的实现。
Mouse Cursor Extensions 为 Framework element 提供了一种简单的设置鼠标悬浮时样式的方法,让开发者可以更容易的通过鼠标状态体现每个 Framework element 的状态。接下来看看官方示例的截图:

Doc: https://docs.microsoft.com/zh-cn/windows/uwpcommunitytoolkit/extensions/mousecursor
Namespace: Microsoft.Toolkit.Uwp.UI.Extensions; Nuget: Microsoft.Toolkit.Uwp.UI;
开发过程
代码分析
Mouse Cursor Extensions 的功能实现比较简单,在 Mouse.cs 类中;先看一下类的结构:

我们看到,类中定义了一个依赖属性:
Cursor - 光标属性,标记了 Framework element 对应的光标,默认值是 Arrow 光标,变化时触发 CursorChanged 事件;
获取和设置的方法是 GetCursor(FrameworkElement element) 和 SetCursor(FrameworkElement element, CoreCursorType value);根据 element 获取光标,和根据 element 设置光标;
除此之外,类中还定义了几个 static readonly 的变量:
- _cursorLock - 为保证 cursor 的创建和处理是原子的,所以需要加锁
- _defaultCursor - CoreCursor 类型,记录了鼠标进入 element 前的样式,这样可以在鼠标移出后恢复为原有样式;
- _cursors - Dictionary 类型,记录了 element 间的光标类型和光标的键值对,在切换 element 时,根据这个值确定应该显示什么光标样式;
其中 CoreCursorType 是一个枚举类型,包括:
Arrow = , Cross = , Custom = , Hand = , Help = , IBeam = , SizeAll = , SizeNortheastSouthwest = , SizeNorthSouth = , SizeNorthwestSoutheast = , SizeWestEast = , UniversalNo = , UpArrow = , Wait = , Pin = , Person =
CoreCursorType 和 CoreCursor 都在 Windows.UI.Core 中,大家可以在这个 namespace 中详细查看,或者在 https://docs.microsoft.com/en-us/uwp/api/Windows.UI.Core.CoreCursor 中查看。
CursorChanged 事件的处理方法如下:
把 newValue 加入到 _cursors 字典中,用于 element 切换时获取对应的 Cursor,然后为 element 绑定 PointerEntered,PointerExited,Unloaded 事件。
private static void CursorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var element = d as FrameworkElement;
if (element == null)
{
throw new NullReferenceException(nameof(element));
}
var value = (CoreCursorType)e.NewValue;
// lock ensures CoreCursor creation and event handlers attachment/detachment is atomic
lock (_cursorLock)
{
if (!_cursors.ContainsKey(value))
{
_cursors[value] = );
}
// make sure event handlers are not attached twice to element
element.PointerEntered -= Element_PointerEntered;
element.PointerEntered += Element_PointerEntered;
element.PointerExited -= Element_PointerExited;
element.PointerExited += Element_PointerExited;
element.Unloaded -= ElementOnUnloaded;
element.Unloaded += ElementOnUnloaded;
}
}
分别看一下这三个事件的处理方法:
Element_PointerEntered(s, e) 的处理就是通过 GetCursor(element) 方法获取 CoreCursorType,在 _cursors 字典中获取对应的光标,设置给 Window.Current.CoreWindow.PointerCursor;
private static void Element_PointerEntered(object sender, PointerRoutedEventArgs e)
{
CoreCursorType cursor = GetCursor((FrameworkElement)sender);
Window.Current.CoreWindow.PointerCursor = _cursors[cursor];
}
Element_PointerExited(s, e) 的处理是判断光标移出后,新移入的元素是否为 Framework element,如果是,则获取它对应的 Cursor;如果不是,则恢复为默认的 Cursor;
private static void Element_PointerExited(object sender, PointerRoutedEventArgs e)
{
// when exiting change the cursor to the target Mouse.Cursor value of the new element
CoreCursor cursor;
if (e.OriginalSource is FrameworkElement newElement)
{
cursor = _cursors[GetCursor(newElement)];
}
else
{
cursor = _defaultCursor;
}
Window.Current.CoreWindow.PointerCursor = cursor;
}
ElementOnUnloaded(s, e) 的处理,就是把 Cursor 设置为默认值;
private static void ElementOnUnloaded(object sender, RoutedEventArgs routedEventArgs)
{
// when the element is programatically unloaded, reset the cursor back to default
// this is necessary when click triggers immediate change in layout and PointerExited is not called
Window.Current.CoreWindow.PointerCursor = _defaultCursor;
}
调用示例
我们创建了两个按钮,Cursor 分别设置为 UniversalNo 和 Wait,可以看到光标分别进入这两个按钮时的显示,已经光标离开进去空白处时的显示,和预期是一致的;
<StackPanel Orientation="Horizontal" Padding="20">
<Button Content="Disabled" Width="200" extensions:Mouse.Cursor="UniversalNo"/>
<Button Content="Loading" Width="200" extensions:Mouse.Cursor="Wait"/>
</StackPanel>

总结
到这里我们就把 UWP Community Toolkit Extensions 中的 Mouse Cursor Extensions 的源代码实现过程和简单的调用示例讲解完成了,希望能对大家更好的理解和使用这个扩展有所帮助。欢迎大家多多交流,谢谢!
最后,再跟大家安利一下 UWPCommunityToolkit 的官方微博:https://weibo.com/u/6506046490, 大家可以通过微博关注最新动态。
衷心感谢 UWPCommunityToolkit 的作者们杰出的工作,Thank you so much, UWPCommunityToolkit authors!!!
Extensions in UWP Community Toolkit - Mouse Cursor的更多相关文章
- Extensions in UWP Community Toolkit - Overview
概述 UWP Community Toolkit 中有一个 Extensions 的集合,它们可以帮助开发者实现很多基础功能,省去自己造轮子的过程,本篇我们先来看一下 Extensions 的功能都 ...
- Extensions in UWP Community Toolkit - FrameworkElement Extensions
概述 UWP Community Toolkit Extensions 中有一个为FrameworkElement 提供的扩展 - FrameworkElement Extensions,本篇我们结合 ...
- Extensions in UWP Community Toolkit - SurfaceDialTextbox
概述 UWP Community Toolkit Extensions 中有一个为TextBox 提供的 SurfaceDial 扩展 - SurfaceDialTextbox,本篇我们结合代码详细讲 ...
- Extensions in UWP Community Toolkit - ViewExtensions
概述 UWP Community Toolkit Extensions 中有一个为 View 提供的扩展 - View Extensions,本篇我们结合代码详细讲解 View Extensions ...
- Extensions in UWP Community Toolkit - Visual Extensions
概述 UWP Community Toolkit Extensions 中有一个为可视元素提供的扩展 - VisualExtensions,本篇我们结合代码详细讲解 VisualExtensions ...
- Extensions in UWP Community Toolkit - WebViewExtensions
概述 UWP Community Toolkit Extensions 中有一个为 WebView 提供的扩展 - WebViewExtensions,本篇我们结合代码详细讲解 WebView Ext ...
- Extensions in UWP Community Toolkit - ListViewExtensions
概述 UWP Community Toolkit Extensions 中有一个为 ListView 提供的扩展 - ListViewExtensions,本篇我们结合代码详细讲解 ListView ...
- New UWP Community Toolkit
概述 UWP Community Toolkit 是一个 UWP App 自定义控件.应用服务和帮助方法的集合,能够很大程度的简化和指引开发者的开发工作,相信广大 UWPer 并不陌生. 下面是截取自 ...
- New UWP Community Toolkit - Carousel
概述 New UWP Community Toolkit V2.2.0 的版本发布日志中提到了 Carousel 的调整,本篇我们结合代码详细讲解 Carousel 的实现. Carousel 是 ...
随机推荐
- Vim修炼秘籍之语法篇
前言 少年,我看你骨骼精奇,是万中无一的武学奇才,维护世界和平就靠你了,我这有本秘籍<Vim修炼秘籍>,见与你有缘,就十块卖给你了! 如果你是一名 Vimer,那么恭喜你,你的 Vim 技 ...
- nslookup命令的安装及使用
windows中是自带的,不用安装,直接在cmd窗口直接使用 Linux中需要安装: yum -y install bind-utils nslookup www.baidu.com [root@bo ...
- cesium Animation显示系统时间
var d = new Date(); var hour = 0 - d.getTimezoneOffset(); viewer.animation.viewModel.timeFormatter = ...
- java编程基础知识及常见例题
⒈标识符: 只能包含数字.字母.下划线.$,并且不能以数字开头.语义直观规范 驼峰法则: 如:方法名.变量名采用驼峰法则 帕斯卡命名法: 如: 类.接口.枚举采用帕斯卡命名法包名:网址倒写,com.网 ...
- 【Linux】 升级CentOS6的内核到3.10
升级内核 最近有一些虚拟机,想装Dokcer,但是实验之后发现Docker基本上只在3.0以上的linux内核版本中才能稳定运行.所以就面临着把CentOS6的2.6内核升级到3.0以上.下面提供两种 ...
- 大数据 --> Kafka集群搭建
Kafka集群搭建 下面是以三台机器搭建为例,(扩展到4台以上一样,修改下配置文件即可) 1.下载kafka http://apache.fayea.com/kafka/0.9.0.1/ ,拷贝到三台 ...
- SQL语法语句总结
一.SQL语句语法 ALTER TABLE ALTER TABLE 用来更新已存在表的结构. ALTER TABLE tablename (ADD|DROP column datatype [NULL ...
- 0x02 译文:Windows桌面应用Win32第一个程序
本节课我们将用C++ 写一个最简单的Windows 程序. 目录: 创建一个窗口 窗口消息 编写窗口过程 绘制窗口 关闭窗口 管理应用程序状态 代码如下: #ifndef UNICODE #defin ...
- SQL注入之Sqli-labs系列第一篇
在开始接触渗透测试开始,最初玩的最多的就是Sql注入,注入神器阿D.明小子.穿山甲等一切工具风靡至今.当初都是以日站为乐趣,从安全法实施后在没有任何授权的情况下,要想练手只能本地环境进行练手,对于sq ...
- poj3358 Period of an Infinite Binary Expansion
Period of an Infinite Binary Expansion 题目大意:给你一个分数,求这个分数二进制表示下从第几位开始循环,并求出最小循环节长度. 注释:int范围内. 想法:这题说 ...