一、键盘类和键盘事件

WPF提供了基础的键盘类(System.Input.Keyboard类),该类提供与键盘相关的事件、方法和属性,这些事件、方法和属性提供有关键盘状态的信息。Keyboard的事件也通过UIElement等XAML基元素类的事件向外提供。

对于键盘操作,其常用的事件有两组:

KeyDown事件和PreviewKeyDown事件:处理键盘键按下
KeyUp事件和PreviewKeyUp事件:处理键盘键抬起
其中KeyDown和KeyUp事件属于冒泡路由事件,而PreviewKeyDown和PreviewKeyup属于隧道路由事件。

为了使元素能够接收键盘输入,该元素必须可获得焦点。默认情况下,大多数 UIElement 派生对象都可获得焦点。如果不是这样,则要使元素可获得焦点,请将基元素上的 Focusable 属性设置为 true。像 StackPanel 和 Canvas 这样的 Panel 类将 Focusable 的默认值设置为 false。因此,对要获取键盘焦点的这些对象而言,必须将 Focusable 设置为 true。

例如:在笔者的Notebook中有“静音”、“增大音量”、“减小音量”这三个快捷键,在一个应用程序的窗体上处理这三个键的点击可以:

: <Window x:Class="InputCommandAndFocus.Window1"
: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
: Title="Window1" Height="" Width=""
: Focusable="True" PreviewKeyDown="Window_PreviewKeyDown">
: <Canvas>
: <!-- ... -->
: </Canvas>
: </Window>
: private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
: {
: if (e.Key == Key.VolumeMute)
: {
: // 按下“静音”键
: txtMessage.Text = "Mute";
: e.Handled = true;
: }
: else if (e.Key == Key.VolumeUp)
: {
: // 按下“增大音量”键
: txtMessage.Text = "Up";
: e.Handled = true;
: }
: else if (e.Key == Key.VolumeDown)
: {
: // 按下“减小音量”键
: txtMessage.Text = "Down";
: e.Handled = true;
: }
: }

二、鼠标类和鼠标事件

WPF提供的System.Input.Mouse类提供与鼠标相关的事件、方法和属性,这些事件、方法和属性提供有关鼠标状态的信息。与Keyboard类类似,其事件也通过UIElement等基元素向外提供。

其事件主要有以下几组(每个事件均包含XXX冒泡路由事件和PreviewXXX隧道路由事件)

MouseDown、MouseUp事件:处理鼠标键的按下与抬起
MouseEnter、MouseLeave、MouseMove:处理鼠标进入、离开控件及在控件上移动
MouseWheel:处理鼠标滚轮滚动
另外,对于鼠标位置的捕获,使用Mouse类的GetPosition方法,其参数是一个UIElement,表示其鼠标位置基于哪一个控件的坐标系。

例如,对于一个矩形图形,设置其鼠标的各种事件:

: <Rectangle Canvas.Left="" Canvas.Top="" Height=""
: Name="mainRectangle" Stroke="Black" Width="" Fill="White"
: MouseEnter="mainRectangle_MouseEnter" MouseLeave="mainRectangle_MouseLeave"
: MouseMove="mainRectangle_MouseMove" MouseDown="mainRectangle_MouseDown"
: MouseWheel="mainRectangle_MouseWheel"/>
: private void mainRectangle_MouseEnter(object sender, MouseEventArgs e)
: {
: // 鼠标进入控件时,控件的颜色为红色
: mainRectangle.Fill = new SolidColorBrush(Colors.Red);
: }
:
: private void mainRectangle_MouseLeave(object sender, MouseEventArgs e)
: {
: // 鼠标离开控件时,控件的颜色为红色
: mainRectangle.Fill = new SolidColorBrush(Colors.White);
: }
:
: private void mainRectangle_MouseMove(object sender, MouseEventArgs e)
: {
: // 获取基于Rectangle的鼠标的坐标
: Point pointBaseRectangle = Mouse.GetPosition(mainRectangle);
: txtMessage.Text = string.Format(
: "Mouse Position (Base the Rectangle) is ({0},{1})",
: pointBaseRectangle.X, pointBaseRectangle.Y);
:
: txtMessage.Text += "\r\n";
:
: // 获取基于窗体的鼠标的坐标
: Point pointBaseWindow = Mouse.GetPosition(this);
: txtMessage.Text += string.Format(
: "Mouse Position (Base the Window) is ({0},{1})",
: pointBaseWindow.X, pointBaseWindow.Y);
: }
:
: private void mainRectangle_MouseDown(object sender, MouseButtonEventArgs e)
: {
: // 获取点出的鼠标的按钮
: MouseButton button = e.ChangedButton;
:
: txtMessage.Text += "\r\n";
: txtMessage.Text += string.Format(
: " Mouse Button is {0}", button.ToString());
: }
:
: private void mainRectangle_MouseWheel(object sender, MouseWheelEventArgs e)
: {
: if (e.Delta > )
: {
: // 如果向上推动滚轮,图形的宽度增加
: rectangle1.Width++;
: }
:
: if (e.Delta < )
: {
: // 如果向下推动滚轮,图形的宽度减小
: rectangle1.Width--;
: }
: }

三、焦点处理

在 WPF 中,有两个与焦点有关的主要概念:键盘焦点和逻辑焦点。 键盘焦点指接收键盘输入的元素,而逻辑焦点指焦点范围中具有焦点的元素。

1、键盘焦点:

键盘焦点指当前正在接收键盘输入的元素。 在整个桌面上,只能有一个具有键盘焦点的元素。 在 WPF 中,具有键盘焦点的元素会将 IsKeyboardFocused 设置为 true。 Keyboard 类的静态属性 FocusedElement 获取当前具有键盘焦点的元素。

为了使元素能够获取键盘焦点,基元素的 Focusable 和 IsVisible 属性必须设置为 true。 有些类(如 Panel 基类)默认情况下将 Focusable 设置为 false;因此,如果您希望此类元素能够获取键盘焦点,必须将 Focusable 设置为 true。

可以通过用户与 UI 交互(例如,按 Tab 键定位到某个元素或者在某些元素上单击鼠标)来获取键盘焦点。 还可以通过使用 Keyboard 类的 Focus 方法,以编程方式获取键盘焦点。 Focus 方法尝试将键盘焦点给予指定的元素。 返回的元素是具有键盘焦点的元素,如果有旧的或新的焦点对象阻止请求,则具有键盘焦点的元素可能不是所请求的元素。

2、逻辑焦点

逻辑焦点指焦点范围中的 FocusManager..::.FocusedElement。 焦点范围是一个跟踪其范围内的 FocusedElement 的元素。 当键盘焦点离开焦点范围时,焦点元素会失去键盘焦点,但保留逻辑焦点。 当键盘焦点返回到焦点范围时,焦点元素会再次获得键盘焦点。 这使得键盘焦点可以在多个焦点范围之间切换,但确保了在焦点返回到焦点范围时,焦点范围中的焦点元素再次获得键盘焦点。

一个应用程序中可以有多个具有逻辑焦点的元素,但在一个特定的焦点范围中只能有一个具有逻辑焦点的元素。

GetFocusScope 返回指定元素的焦点范围。

WPF 中默认情况下即为焦点范围的类有 Window、MenuItem、ToolBar 和 ContextMenu。

GetFocusedElement 获取指定焦点范围的焦点元素。SetFocusedElement 设置指定焦点范围中的焦点元素。SetFocusedElement 通常用于设置初始焦点元素。

3、键盘导航

当按下导航键之一时,KeyboardNavigation 类将负责实现默认键盘焦点导航。 导航键有:Tab、Shift+Tab、Ctrl+Tab、Ctrl+Shift+Tab、向上键、向下键、向左键和向右键。

可以通过设置附加的 KeyboardNavigation 属性 TabNavigation、ControlTabNavigation 和 DirectionalNavigation 来更改导航容器的导航行为。 这些属性是 KeyboardNavigationMode 类型,可能值有 Continue、Local、Contained、Cycle、Once 以及 None。 默认值是 Continue,这意味着元素不是导航容器。

4、焦点事件
与键盘焦点相关的事件有 PreviewGotKeyboardFocus、GotKeyboardFocus、PreviewLostKeyboardFocus 以及 LostKeyboardFocus。 这些事件定义为 Keyboard 类的附加事件,但更便于作为基元素类上的等效路由事件来访问。

当元素获取键盘焦点时,会引发 GotKeyboardFocus。当元素失去键盘焦点时,会引发 LostKeyboardFocus。 如果处理了 PreviewGotKeyboardFocus 事件或 PreviewLostKeyboardFocusEvent 事件,并且 Handled 设置为 true,则焦点将不会改变。

PS:本文非原创,从其它处搬运过来供自己学习,在此感谢原作者

wpf键盘的更多相关文章

  1. wpf键盘记录器

    很简单的一个wpf键盘记录器 这个程序我一样用了全局勾子,之前用的都是winform上运行了,前一段时间 在国外的论坛上逛看到了一个wpf能用的就做了一个小程序记录一下,为了方便大家直关的看我在页面上 ...

  2. WPF 键盘全局接收消息

    1.========================================================================== 在c#中怎样禁用鼠标左键的使用,其实我们可以通 ...

  3. WPF 键盘事件

    private void Window_KeyDown(object sender, KeyEventArgs e) { if (e.KeyStates==Keyboard.GetKeyStates( ...

  4. 16Aspx.com源码2014年7月详细

            Web电子商务网(三层)V2.0源码 2014-07-31   [VS2010] 源码介绍: Web电子商务网(三层)V2.0源码 源码描述: 一.源码特点     采用三层架构开发, ...

  5. [译].NET Framework 4.8发布

    原文地址:https://devblogs.microsoft.com/dotnet/announcing-the-net-framework-4-8/ 我们很高兴地宣布今天发布.NET Framew ...

  6. WPF 虚拟键盘

    之前做了一款WPF虚拟键盘,调用Win32的API,可以模拟键盘事件. 现将代码分享如下: 按键布局如下: <Button Name="> <StackPanel Orie ...

  7. [分享]WPF 虚拟键盘

    场景:用WPF做触屏的软件难免会需要用户输入的问题,至少是简单的数字,这个时候就免不了需要键盘输入. 思路:既然是虚拟键盘,那么我的目的就是模拟键盘输入即可. 1.模拟键盘输入 模拟键盘输入?那么肯定 ...

  8. wpf之Popup弹出自定义输入"键盘"

    在很多工厂的信息化MES系统中,车间的采集数据的机器是触摸屏电脑(工厂环境所限,用外接鼠标键盘反而不方便). 由于没有外接键盘,所以用户无法像坐在办公室一样,用鼠标键盘进行录入信息. 这时我们可以用w ...

  9. WPF 中模拟键盘和鼠标操作

    转载:http://www.cnblogs.com/sixty/archive/2009/08/09/1542210.html 更多经典文章:http://www.qqpjzb.cn/65015.ht ...

随机推荐

  1. 【Luogu P3375】字符串匹配KMP算法模板

    Luogu P3375 模式串:即题目中的S2所代表的意义 文本串:即题目中的S1所代表的意义 对于字符串匹配,有一种很显然的朴素算法:在S1中枚举起点一位一位匹配,失配之后起点往后移动一位,从头开始 ...

  2. mr的partition分区

    1.Partitioner 组件通过让 Map 对 Key 进行分区,从而将不同分区的 Key 交由不同的 Reduce 处理.Partition属于map端 2.分区的总数与任务的reduce任务数 ...

  3. 浅谈集群版Redis和Gossip协议

    昨天的文章写了关于分布式系统中一致性哈希算法的问题,文末提了一下Redis-Cluster对于一致性哈希算法的实现方案,今天来看一下Redis-Cluster和其中的重要概念Gossip协议. 1.R ...

  4. 【软件工具】easyExcel简明使用指南

    easyExcel简介 Java领域解析.生成Excel比较有名的框架有Apache poi.jxl等.但他们都存在一个严重的问题就是非常的耗内存.如果你的系统并发量不发的话可能还行,但是一旦并发上来 ...

  5. MySQL多索引查询选择

    MySQL多索引查询选择 MySQL选择索引-引入 我们知道我们一个表里面可以有多个索引的,那么我们查询数据的时候不指定索引,MySQL就会帮我们自动选择.既然是MySQL程序帮我们自动选择的那么会不 ...

  6. Oracle temp table

    Tow kinds of temp table data keep method. One is delete when commit Anothe one is preseve when commi ...

  7. c语言l博客作业02

    问题 答案 这个作业属于哪个课程 C语言程序设计l 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/SE2019-2/homework/8687 我在这个 ...

  8. jQuery九宫格抽奖

    <div id="box"> <div class="content content-1">1</div> <div ...

  9. Netty学习——Apache Thrift 简介和下载安装

    Netty学习——Apache Thrift 简介和下载安装 Apache Thrift 简介 本来由Facebook开发,捐献给了Apache,成了Apache的一个重要项目 可伸缩的,跨语言的服务 ...

  10. 《Windows内核安全与驱动开发》 4.4 线程与事件

    <Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发> 4.4 线程与事件 一.开辟一个线程,参数为(打印内容+打印次数),利用线程 ...