C# 自定义并动态切换光标
系统有很多光标类型 :Cursors 类 (System.Windows.Input) | Microsoft Docs
本章介绍如何自定义光标、并动态切换光标类型。
动态切换光标类型
以白板书写为例:鼠标操作时,Cursor为红点;触摸时,Cursor为空;
1 public MainWindow()
2 {
3 InitializeComponent();
4 MouseEnter += (s, e) =>
5 {
6 ShowMouseCursor(e);
7 };
8 MouseMove += (s, e) =>
9 {
10 ShowMouseCursor(e);
11 };
12 StylusMove += (s, e) =>
13 {
14 ShowNoneCursor();
15 };
16 }
设置光标显示:
1 private void ShowNoneCursor()
2 {
3 if (Cursor == Cursors.None)
4 {
5 return;
6 }
7 Cursor = Cursors.None;
8 Mouse.UpdateCursor();
9 }
10 private void ShowMouseCursor(MouseEventArgs e)
11 {
12 if (e.StylusDevice != null && e.StylusDevice.Id > -1)
13 {
14 return;
15 }
16 if (Cursor == GetFillCursor())
17 {
18 return;
19 }
20 Cursor = GetFillCursor();
21 Mouse.UpdateCursor();
22 }
23 private Cursor _fillCursor = null;
24 private Cursor GetFillCursor()
25 {
26 return _fillCursor ?? (_fillCursor = CursorHelper.CreateFillCursor());
27 }
触摸书写时,会有个默认光标,所以此处把触摸时的光标置空Cursors.None。
Mouse.UpdateCursor()能强制更新光标。当然,不调用这个更新方法肉眼其实也看不出啥。。。

光标切换效果如上,前面一段是用鼠标书写,后面是触摸书写,光标类型有切换。红点光标自定义方案见下方。
自定义光标
自定义一个纯色的圆形光标:
1 public static Cursor CreateFillCursor(int size = 24, Brush fillBrush = null)
2 {
3 int unitSize = size / 4;
4 var bmp = new Bitmap(size, size);
5 using (Graphics g = Graphics.FromImage(bmp))
6 {
7 g.Clip = new Region(new Rectangle(0, 0, size, size));
8 g.SmoothingMode = SmoothingMode.HighQuality;
9 g.InterpolationMode = InterpolationMode.HighQualityBicubic;
10 using (var pen = new Pen(fillBrush ?? Brushes.Red, unitSize))
11 {
12
13 g.DrawEllipse(pen, new Rectangle(unitSize, unitSize, unitSize, unitSize));
14 }
15 }
16 return BitmapCursor.CreateBmpCursor(bmp);
17 }
也可以通过图片资源BitmapSource来生成光标:
1 public static Cursor CreateFromBitmapSource(BitmapSource source)
2 {
3 var bitmap = BitmapSourceToBitmap(source);
4 return BitmapCursor.CreateBmpCursor(bitmap);
5 }
6 private static Bitmap BitmapSourceToBitmap(BitmapSource source)
7 {
8 using (var stream = new MemoryStream())
9 {
10 var e = new BmpBitmapEncoder();
11 e.Frames.Add(BitmapFrame.Create(source));
12 e.Save(stream);
13
14 var bmp = new Bitmap(stream);
15
16 return bmp;
17 }
18 }
BitmapCursor:

1 internal class BitmapCursor : SafeHandle
2 {
3 public override bool IsInvalid => handle == (IntPtr)(-1);
4
5 public static Cursor CreateBmpCursor(Bitmap cursorBitmap)
6 {
7
8 var c = new BitmapCursor(cursorBitmap);
9
10 return CursorInteropHelper.Create(c);
11 }
12 protected BitmapCursor(Bitmap cursorBitmap)
13 : base((IntPtr)(-1), true)
14 {
15 handle = cursorBitmap.GetHicon();
16 }
17 protected override bool ReleaseHandle()
18 {
19 bool result = DestroyIcon(handle);
20
21 handle = (IntPtr)(-1);
22
23 return result;
24 }
25 [DllImport("user32")]
26 private static extern bool DestroyIcon(IntPtr hIcon);
27 }
博客参考:
C# 自定义并动态切换光标的更多相关文章
- springboot多数据源动态切换和自定义mybatis分页插件
1.配置多数据源 增加druid依赖 完整pom文件 数据源配置文件 route.datasource.driver-class-name= com.mysql.jdbc.Driver route.d ...
- springAOP实现基于注解的数据源动态切换
需求 代码实现读写数据库分离 武器 spring3.0以上版本 实现思路 1.继承org.springframework.jdbc.datasource.lookup.AbstractRoutingD ...
- Spring3 整合Hibernate3.5 动态切换SessionFactory (切换数据库方言)
一.缘由 上一篇文章Spring3.3 整合 Hibernate3.MyBatis3.2 配置多数据源/动态切换数据源 方法介绍到了怎么样在Sping.MyBatis.Hibernate整合的应用中动 ...
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...
- Spring动态切换多数据源解决方案
Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性.而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时 ...
- SpringBoot 动态切换多数据源
1. 配置文件application-dev.properties 2. 动态切换数据源核心 A. 数据源注册器 B. 动态数据源适配器 C. 自定义注解 D. 动态数据源切面 E. 数据源路 ...
- springboot 双数据源+aop动态切换
# springboot-double-dataspringboot-double-data 应用场景 项目需要同时连接两个不同的数据库A, B,并且它们都为主从架构,一台写库,多台读库. 多数据源 ...
- 【原】通过AOP实现MyBatis多数据源的动态切换
[环境参数]1.开发框架:Spring + SpringMVC + MyBatis 2.数据库A的URL:jdbc.url=jdbc:mysql://172.16.17.164:3306/ test? ...
- ExtJS动态切换主题
ExtJS动态切换主题 在Sencha Cmd构建的Ext程序中怎么去动态切换主题,目前看好像只能单一切换,但是在官网文档找到了答案 Resource Management在上一节通过 ...
随机推荐
- Docker不启动容器的情况下修改配置文件
应用场景: 1.容器中配置文件错误无法启动. 2.任何不启动容器时修改配置文件. 方法: 1.Copy容器中的配置文件出来. 2.修改此配置文件 3.将配置文件重新覆盖回容器内 命令 docker c ...
- HTML笔记(二) HTML标签元素
一 常用的头部元素标签 <head>元素包含了所有的头部标签元素. 1.<title> <title>标签定义了HTML文档的标题,在HTML/XHTML文档中是必 ...
- TAP 交换机
首发第一篇,就想分享一下TAP交换机的网络设备,为啥要谈这个呢,因为是一个冷门产品,大厂一般都没有,有也不作为重点产品推介,所以关注的人少,希望能给有这方面需求的人,又苦于找不到介绍资料的人以帮助.在 ...
- Android Studio Dolphin 稳定版正式发布
作者 / Yuri Blaise, Product Manager, Android为了帮助开发者们更轻松地打造高质量应用,Android Studio 团队深入调研,为大家带来了最新稳定版 An ...
- NX二次开发获取当前DLL路径函数
string GetPath();//输出程序路径 string YiNingToolPath(string DLLDir); //分割程序路径获取工具目录 HMODULE GetSelfModule ...
- Linux 截图快捷键 - 搬运
Linux 截图快捷键 转自:linux 截图快捷键 环境 Linux Mint 21.1 1. Prt ScSysRq ---->全屏截图2. Shift+Prt ScSysRq ----& ...
- 带你深入Java Log框架,彻底搞懂Log4J、Log4J2、LogBack,SLF4J
最近系统被扫出来还在使用老旧的log4j,需要升级到最新的log4j.但是在升级的发现,Java相关的日志处理库有log4j, log4j2,slf4j和logback,初一看确实有点头大,那么区别是 ...
- 在surging 微服务引擎下如何搭建webservice和身份验证
一.前言 现实生产中,有一些比较老的系统对外提供的接口都是WebService,尤其是比较老的系统都是围绕ESB进行搭建,而对外提供就需要WebService ,为了更好完善其解决方案,故集成了web ...
- 剑指 offer 第 28 天
第 28 天 搜索与回溯算法(困难) 剑指 Offer 37. 序列化二叉树 请实现两个函数,分别用来序列化和反序列化二叉树. 你需要设计一个算法来实现二叉树的序列化与反序列化.这里不限定你的序列 / ...
- react组件之非受控组件和高阶组件
非受控组件 受控组件和非受控组件的区别 ----- value import React, { Component } from 'react' export default class extend ...