系统有很多光标类型 :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# 自定义并动态切换光标的更多相关文章

  1. springboot多数据源动态切换和自定义mybatis分页插件

    1.配置多数据源 增加druid依赖 完整pom文件 数据源配置文件 route.datasource.driver-class-name= com.mysql.jdbc.Driver route.d ...

  2. springAOP实现基于注解的数据源动态切换

    需求 代码实现读写数据库分离 武器 spring3.0以上版本 实现思路 1.继承org.springframework.jdbc.datasource.lookup.AbstractRoutingD ...

  3. Spring3 整合Hibernate3.5 动态切换SessionFactory (切换数据库方言)

    一.缘由 上一篇文章Spring3.3 整合 Hibernate3.MyBatis3.2 配置多数据源/动态切换数据源 方法介绍到了怎么样在Sping.MyBatis.Hibernate整合的应用中动 ...

  4. Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法

    一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...

  5. Spring动态切换多数据源解决方案

    Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性.而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时 ...

  6. SpringBoot 动态切换多数据源

    1. 配置文件application-dev.properties 2. 动态切换数据源核心 A. 数据源注册器 B. 动态数据源适配器 C. 自定义注解 D. 动态数据源切面     E. 数据源路 ...

  7. springboot 双数据源+aop动态切换

    # springboot-double-dataspringboot-double-data 应用场景 项目需要同时连接两个不同的数据库A, B,并且它们都为主从架构,一台写库,多台读库. 多数据源 ...

  8. 【原】通过AOP实现MyBatis多数据源的动态切换

    [环境参数]1.开发框架:Spring + SpringMVC + MyBatis 2.数据库A的URL:jdbc.url=jdbc:mysql://172.16.17.164:3306/ test? ...

  9. ExtJS动态切换主题

    ExtJS动态切换主题         在Sencha Cmd构建的Ext程序中怎么去动态切换主题,目前看好像只能单一切换,但是在官网文档找到了答案 Resource Management在上一节通过 ...

随机推荐

  1. npm proxy问题

    检查你的电脑是否需要配置代理,如果不需要可以将代理禁用: npm config set proxy false 如果是需要配置代理服务的: 开启代理 npm config set proxy true ...

  2. form表单 css的选择器和一些属性以及盒子模型,浮动

    form表单 <form action='' method='' enctype=''> <input type='text'> input:更下type属性就可以得到对应的效 ...

  3. Java学习笔记-封装Java Util包Base64方法

    懒人菜鸟入门Java系列-习惯性封装常用方法,方便开发过程中调用   注释: Java版本-1.8 1 * @Author wuwenchao 2 * @Version 1.0.0 3 * @Date ...

  4. String当中的intern()

    public class String001 { public static void main(String[] args) { String s1 = "hello"; Str ...

  5. mysql查询增加自增列

    mysql> SELECT a.user, @i:=@i+1 as id FROM user a,(SELECT @i:=0) b; +------------------+------+| u ...

  6. CentOS7更改阿里源

    阿里云yum源:1)备份当前yum源防止出现意外还可以还原回来cd /etc/yum.repos.d/cp /CentOS-Base.repo /CentOS-Base-repo.bak2)使用wge ...

  7. 软件工程日报——第十天(Android 开发中的异常处理问题)

    Android 开发中的异常处理问题 在代码的编写工作当中,我们会遇到很多有关错误处理的内容.这个时候,你用的最多的应该是try-catch-finally,这样的句式.系统提供的这个句式极大方便我们 ...

  8. LoadRunner——安装教程以及创建与录制(一)

    theme: channing-cyan 1. loadrunner12|loadrunner12官方版下载(附安装教程)+网盘下载+汉化包 CSDN下载及安装教程: https://blog.csd ...

  9. Dubbo和Zookeeper(Springboot集成)

    Dubbo和Zookeeper集成: 分布式理论: 分布式系统是由一组通过网络进行通信.为了完成共同的任务而协调工作的计算机节点组成的系统.分布式系统的出现是为了用廉价的.普通的机器完成单个计算机无法 ...

  10. Java笔记第三弹

    Map集合的获取功能 V get(Object key);//根据键获取值 Set<K> keySet();//获取所有键的集合 Collection<K> values(); ...