WPF三大基础元素:键盘、鼠标与焦点

这篇具有很好参考价值的文章主要介绍了WPF三大基础元素:键盘、鼠标与焦点。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

键盘类与事件处理

  • WPF框架中内置了System.Input.Keyboard基础键盘类,该类提供了丰富的键盘相关功能,包括描述键盘状态的属性、处理键盘操作的方法以及一系列事件。这些键盘事件不仅直接由Keyboard类提供,还通过UIElement等XAML基元素类向外传递。
  • 处理键盘输入时,常用的两个事件组是:
  1. KeyDown和PreviewKeyDown事件:当键盘键按下时,这两个事件会被触发KeyDown事件属于冒泡路由事件,这意味着它会从底层元素向上传播到包含它的元素。而PreviewKeyDown事件隧道路由事件,它会将事件沿着逻辑树向上传递,直到它被处理或路由到根元素
  2. KeyUp和PreviewKeyUp事件:当键盘键释放时,这两个事件会被触发KeyUp事件同样是冒泡路由事件,而PreviewKeyUp事件则是隧道路由事件
  • 如果要使某个UI元素能够接收并响应键盘输入,首要条件是该元素必须具有焦点。大部分UIElement的派生类默认都可获取焦点,但是像StackPanel和Canvas这类Panel类,默认情况下其Focusable属性被设置为false,因此不能直接获取焦点。若需此类元素能响应键盘输入,则需要显式将其Focusable属性设为true
  • 下面写个以PreviewKeyDown为例子:
<Window x:Class="WpfKeyboardEventsApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfKeyboardEventsApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"  Focusable="True" PreviewKeyDown="Window_PreviewKeyDown">
    <Grid>
        <!--添加TextBlock用来显示键盘输入显示效果-->
        <TextBlock x:Name="myTextBlock" Text="这里演示“静音”、“增大音量”、“减小音量”这三个快捷键" Foreground="White" Background="Green" FontSize="16"  Height="33" Padding="10,6"  HorizontalAlignment="Center"></TextBlock>

    </Grid>
</Window>
using System.Windows;
using System.Windows.Input;

namespace WpfKeyboardEventsApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.VolumeMute)
            {
                // 按下“静音”键
                myTextBlock.Text = "按下“静音”键";
                e.Handled = true;
            }
            else if (e.Key == Key.VolumeUp)
            {
                // 按下“增大音量”键
                myTextBlock.Text = "按下“增大音量”键";
                e.Handled = true;
            }
            else if (e.Key == Key.VolumeDown)
            {
                // 按下“减小音量”键
                myTextBlock.Text = "按下“减小音量”键";
                e.Handled = true;
            }

        }

    }
}

上述代码,当用户在窗口中按下键盘按键时,将调用名为Window_PreviewKeyDown的事件处理程序来处理按键事件。效果如下:
wpf previewmouseup 事件,wpf,计算机外设

鼠标类与鼠标事件处理

  • WPF框架内建的System.Input.Mouse类为开发人员提供了丰富的鼠标相关功能,涵盖了关于鼠标状态的各种事件、方法及属性。类似于键盘事件的处理方式,Mouse类所包含的这些事件同样通过UIElement和其他XAML基元素类传递给应用程序。
  • 鼠标事件主要分为以下几个类别,每个类别都有对应的冒泡路由事件和隧道路由事件对:
  1. MouseDown和PreviewMouseDown事件:当用户按下鼠标按钮时触发,用于响应鼠标键按下动作。
  2. MouseUp和PreviewMouseUp事件:在用户释放鼠标按钮时发生,用于处理鼠标键抬起的动作。
  3. MouseEnter和PreviewMouseEnter事件:当鼠标光标进入控件区域时通知,标志着鼠标从外部移入控件。
  4. MouseLeave和PreviewMouseLeave事件:当鼠标离开控件边界时激活,表明鼠标从控件内部移至外部区域。
  5. MouseMove和PreviewMouseMove事件:随着鼠标在控件范围内移动而持续触发,可用于实时追踪鼠标的移动轨迹。
    要对于获取精确的鼠标位置,可通过调用Mouse类的GetPosition静态方法,该方法接受一个UIElement参数,返回的是相对于指定控件坐标系内的鼠标位置坐标,从而使得开发者能够根据具体控件上下文来捕获并处理鼠标的位置变化。
  • 下面写个例子:
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <!--添加一个矩形来演示鼠标的相关操作-->
    <Rectangle x:Name="myRectangle" Grid.Row="0"  Canvas.Left="246" Canvas.Top="46" Height="118"  Stroke="Black"  Width="200" Fill="White"
               MouseEnter="myRectangle_MouseEnter" MouseLeave="myRectangle_MouseLeave" 
               MouseMove="myRectangle_MouseMove" MouseDown="myRectangle_MouseDown"
               MouseWheel="myRectangle_MouseWheel"></Rectangle>

    <!--添加TextBlock来显示相关提示-->
    <TextBlock x:Name="myTextBlock" Grid.Row="1" HorizontalAlignment="Center" FontSize="16" Foreground="Green" Text="鼠标滚动会改变矩形的宽度"></TextBlock>

</Grid>
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace WpfKeyboardEventsApp
{
    /// <summary>
    /// MouseWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MouseWindow : Window
    {
        public MouseWindow()
        {
            InitializeComponent();
        }

        private void myRectangle_MouseEnter(object sender, MouseEventArgs e)
        {
            // 鼠标进入控件时,控件的颜色为蓝色
            myRectangle.Fill = new SolidColorBrush(Colors.Blue);
        }

        private void myRectangle_MouseLeave(object sender, MouseEventArgs e)
        {
            // 鼠标离开控件时,控件的颜色为白色
            myRectangle.Fill = new SolidColorBrush(Colors.White);
        }

        private void myRectangle_MouseMove(object sender, MouseEventArgs e)
        {
            // 获取基于Rectangle的鼠标的坐标
            Point pointBaseRectangle = Mouse.GetPosition(myRectangle);
            myTextBlock.Text = $"鼠标位置矩形的底部为 ({pointBaseRectangle.X},{pointBaseRectangle.Y})";

            myTextBlock.Text += "\r\n";

            // 获取基于窗体的鼠标的坐标
            Point pointBaseWindow = Mouse.GetPosition(this);
            myTextBlock.Text += $"鼠标位置基于窗口为 ({pointBaseWindow.X},{pointBaseWindow.Y})";
        }

        private void myRectangle_MouseDown(object sender, MouseButtonEventArgs e)
        {
            // 获取点出的鼠标的按钮,是左边还是右边
            MouseButton button = e.ChangedButton;

            myTextBlock.Text += "\r\n";
            myTextBlock.Text += $"鼠标按键是{button.ToString()}";
        }

        private void myRectangle_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (e.Delta > 0)
            {
                // 如果向上推动滚轮,图形的宽度增加
                myRectangle.Width++;
            }

            if (e.Delta < 0)
            {
                // 如果向下推动滚轮,图形的宽度减小
                myRectangle.Width--;
            }
        }
    }
}

上述代码,包含一个矩形和一个文本块。当用户在矩形上执行鼠标操作时,将调用相应的事件处理程序来处理这些操作。文本块用于显示相关提示信息,效果图如下:
wpf previewmouseup 事件,wpf,计算机外设

WPF中的焦点处理机制

  • 在WPF应用程序中,焦点处理涉及到两个关键概念:键盘焦点和逻辑焦点。其中,键盘焦点特指当前接收键盘输入的元素,而逻辑焦点则是在特定焦点范围内的焦点元素。

1.键盘焦点

  • 是当前接受键盘输入的对象,整个桌面同一时间只能有一个元素拥有键盘焦点。在WPF中,若一个元素具有键盘焦点,其IsKeyboardFocused属性将被设置为true。通过Keyboard类的静态属性FocusedElement可以获取当前拥有键盘焦点的元素。
    若要使某个UI元素能够获取键盘焦点,需要确保该元素的Focusable属性和IsVisible属性均设为true。例如,默认情况下,Panel等基类的Focusable属性为false,因此需手动设置为true以允许此类元素获取焦点。
    用户可以通过交互操作(如按Tab键切换或点击元素)来改变键盘焦点。此外,还可以使用Keyboard.Focus(element)方法以编程方式尝试将键盘焦点赋予指定元素,但返回的结果可能是当前真正获得键盘焦点的元素,因为如果有其他因素阻止了请求,则结果可能与预期不符。
  • 下面来写个例子:
<StackPanel HorizontalAlignment="Center">
    <!--设置Focusable为True 表示可以用键盘获取到焦点-->
    <TextBox x:Name="myTextBox" Focusable="True" Text="我是TextBox1" Margin="0,10"  GotKeyboardFocus="myTextBox_GotKeyboardFocus"/>
    <TextBox x:Name="myTextBox2" Focusable="True" Text="我是TextBox2" Margin="0,10" GotKeyboardFocus="myTextBox_GotKeyboardFocus"/>

    <TextBlock x:Name="myTextBlock" Text="我是一个提示,用来提示谁获取焦点获取焦点" Margin="0,10" Foreground="Red"/>
</StackPanel>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfKeyboardEventsApp
{
    /// <summary>
    /// FocusWindow.xaml 的交互逻辑
    /// </summary>
    public partial class FocusWindow : Window
    {
        public FocusWindow()
        {
            InitializeComponent();
            // 初始化设置myTextBox为焦点
            Keyboard.Focus(myTextBox);
        }

        private void myTextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            myTextBlock.Text = $"{((TextBox)sender).Name} 获取了键盘焦点";
        }
    }
}

上述代码,包含两个输入框和一个文本宽,默认设置第一个输入框为焦点,利用Tab切换,文本显示对应的切换提示,效果图如下:
wpf previewmouseup 事件,wpf,计算机外设

2.逻辑焦点

  • 体现在FocusManager.FocusedElement上,它指的是在一个焦点范围内的焦点元素。当键盘焦点离开焦点范围时,尽管该元素失去了键盘焦点,但仍保留逻辑焦点。当键盘焦点重新回到焦点范围内时,该元素会再次获得键盘焦点,这使得键盘焦点能在多个焦点范围间切换,同时保证焦点返回时,焦点范围内的焦点元素能重获键盘焦点。
    -在一个应用程序中,可以存在多个拥有逻辑焦点的元素,但在单一焦点范围内仅有一个元素拥有逻辑焦点。可通过调用FocusManager.GetFocusScope(element)得到指定元素所在的焦点范围,而FocusManager.GetFocusedElement(scope)用于获取指定焦点范围内的焦点元素,FocusManager.SetFocusedElement(scope, element)则用来设置焦点范围内的焦点元素,通常用于设定初始焦点。
  • 下面来写个例子:
<StackPanel HorizontalAlignment="Center">
    <!--设置TabControl 下面的内容TextBox可以获取到键盘焦点-->
    <TabControl>
        <TabItem Header="Tab导航一">
            <TextBox x:Name="tab1TextBox" Text="我是Tab1的内容,我这里仅仅之作演示" Focusable="True" Foreground="Red"  Height="200"/>
        </TabItem>
        <TabItem Header="Tab导航二">
            <TextBox x:Name="tab2TextBox" Focusable="True" Text="我是Tab2的内容,我这里仅仅之作演示" Foreground="Blue"  Height="200"/>
        </TabItem>
    </TabControl>
</StackPanel>

上述代码,在一个具有多个TabItem的TabControl中,每个TabItem可以视为一个独立的焦点范围。当切换到另一个TabItem时,即使当前TabItem中的元素失去了键盘焦点,它仍保留逻辑焦点。若返回原来的TabItem,先前获得焦点的元素会重新获取键盘焦点,效果图如下:
wpf previewmouseup 事件,wpf,计算机外设

3.键盘导航

  • 当用户按下导航键(如Tab、Shift+Tab、Ctrl+Tab组合键以及方向键)时,KeyboardNavigation类负责实现默认的键盘焦点导航行为。通过设置附加属性KeyboardNavigation.TabNavigation、ControlTabNavigation和DirectionalNavigation,可以自定义导航容器的导航策略,这些属性可取值包括Continue(继续导航。当键盘导航到达元素的末尾时,导航将继续到下一个元素)、Local(本地循环。当键盘导航到达元素的末尾时,导航将从头开始导航元素。)、Contained(包含循环。当键盘导航到达元素的末尾时,导航将从头开始导航元素,直到所有元素都被导航。)、Cycle(循环。当键盘导航到达元素的末尾时,导航将从头开始导航元素,直到所有元素都被导航。)、Once(一次。当键盘导航到达元素的末尾时,导航将停止。)和None(无。当键盘导航到达元素的末尾时,导航将不执行任何操作。),默认为Continue
  • 下面来写个例子:
<StackPanel HorizontalAlignment="Center">
    <!--设置按下Tab键时仅在其内部循环移动焦点,直到所有的都被导航停止-->
    <ListBox KeyboardNavigation.TabNavigation="Contained">
        <ListBoxItem Content="我是ListBox选项1"/>
        <ListBoxItem Content="我是ListBox选项2"/>
        <ListBoxItem Content="我是ListBox选项3"/>
        <ListBoxItem Content="我是ListBox选项4"/>
        <ListBoxItem Content="我是ListBox选项5"/>
        <ListBoxItem Content="我是ListBox选项6"/>
        <ListBoxItem Content="我是ListBox选项7"/>
        <ListBoxItem Content="我是ListBox选项8"/>
    </ListBox>
</StackPanel>

上述代码,ListBox在按下Tab键时仅在其内部循环移动焦点,不跳转到其他控件上,到最后一个元素导航,效果图如下:
wpf previewmouseup 事件,wpf,计算机外设

4.焦点事件

  • 关于键盘焦点的事件包括PreviewGotKeyboardFocus、GotKeyboardFocus、PreviewLostKeyboardFocus以及LostKeyboardFocus。这些事件作为Keyboard类的附加事件,但在实际开发中更常作为基元素类上的路由事件使用。
    具体来说,当元素获取键盘焦点时触发GotKeyboardFocus事件;失去键盘焦点时引发LostKeyboardFocus事件。如果在预处理阶段即PreviewGotKeyboardFocus或 PreviewLostKeyboardFocus事件中设置了Handled为true,则焦点状态将不会发生改变。
  • 下面来写个例子:
<StackPanel HorizontalAlignment="Center">
   <!--设置TextBox添加三个事件-->
   <TextBox x:Name="myTextBox" Focusable="True" PreviewGotKeyboardFocus="myTextBox_PreviewGotKeyboardFocus"  GotKeyboardFocus="myTextBox_GotKeyboardFocus"  LostKeyboardFocus="myTextBox_LostKeyboardFocus" Width="180" Margin="0,10"/>
   <TextBox  Focusable="True" Text="我是用来测试焦点转移" Width="180" Margin="0,10"/>

   <TextBlock x:Name="myTextBlock" Text="我是一个提示,用来提示焦点相关信息"  Foreground="Red" FontSize="16"/>

   <Button Content="设置/取消阻止转移焦点" Click="Button_Click" Width="180"  Margin="0,30" Background="Green" Foreground="White" FontSize="16"></Button>

</StackPanel>
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace WpfKeyboardEventsApp
{
    /// <summary>
    /// FocusWindow.xaml 的交互逻辑
    /// </summary>
    public partial class FocusWindow : Window
    {
        private bool disableFocus = false;  //禁止转移焦点
        public FocusWindow()
        {
            InitializeComponent();
            // 初始化设置myTextBox为焦点
            Keyboard.Focus(myTextBox);
        }

        private void myTextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            //获得焦点
            //myTextBlock.Text = $"{((TextBox)sender).Name} 获取了键盘焦点";
            myTextBlock.Text = $"我获得焦点了";
            myTextBox.Background = Brushes.Yellow;
        }

        private void myTextBox_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            //焦点转移时触发
            if (disableFocus)
            {
                myTextBlock.Text = $"我焦点转移阻止了";
                e.Handled = true; // 阻止焦点转移
            }


        }

        private void myTextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            //失去焦点
            myTextBlock.Text = $"我失去焦点了";
            myTextBox.Background = Brushes.White;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            disableFocus = !disableFocus;
        }
    }
}

上述代码,当TextBox获取或失去键盘焦点时,触发相应的事件,效果图如下:
wpf previewmouseup 事件,wpf,计算机外设

公众号“点滴分享技术猿

wpf previewmouseup 事件,wpf,计算机外设文章来源地址https://www.toymoban.com/news/detail-830048.html

到了这里,关于WPF三大基础元素:键盘、鼠标与焦点的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • js之 事件监听(鼠标、焦点、键盘、文本)

    目标 :能够给DOM元素添加事件监听 什么是事件 :事件是在编程时系统内发生的动作或者发生的事情,比如用户在网页上单击一个按钮 什么是事件监听 :        就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为 绑定事件或者注册事

    2024年02月14日
    浏览(35)
  • CSS基础笔记四,伪类选择器和对象选择器(鼠标点击的四种状态,列表自定义选择,容器只有一个,除了被选中的其他都有,元素为空的时候,元素获得焦点的时候,单选和复选增强)

    伪类选择器  常用有这些: 1,鼠标点击元素的4种状态 爱恨离别(link visited hover active) 前面的2个只适用于 a标签,后面的2个适用于其他标签。顺序不能改变 2,列表中先选择谁就选择谁              first-child  选择开头              last-child 选择结尾       

    2024年02月03日
    浏览(55)
  • Simple WPF:实现一个透明、无边框、鼠标穿透的WPF窗体

    一个自定义WPF窗体的解决方案,借鉴了吕毅老师的WPF制作高性能的透明背景的异形窗口一文,并在此基础上增加了鼠标穿透的功能。可以使得透明窗体的鼠标事件穿透到下层,在下层窗体中响应。这一功能在开发一些截图工具,直播、会议标注工具的时候会有比较多的应用,

    2024年02月09日
    浏览(99)
  • WPF元素绑定

    简单的说,数据绑定是一种关系,该关系告诉WPF从源对象提取一些信息,并用这些信息设置目标对象的属性。目标属性始终是依赖属性,通常位于WPF元素中——毕竟,WPF数据绑定的最终目标是在用户界面中显示一些信息。然而,源对象可以是任何内容,从另一个WPF元素乃至

    2024年02月09日
    浏览(37)
  • C# WPF上位机开发(键盘绘图控制)

    【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】         在软件开发中,如果存在canvas图像的话,一般有几种控制方法。一种是鼠标控制;一种是键盘控制;还有一种是定时器控制。定时器控制,多常见动画、游戏、3d视频当中。而鼠标控制

    2024年02月02日
    浏览(42)
  • WPF快速定位某个元素的相关信息

    运行起WPF程序,使用以下方式,可以快速定位某个元素的信息: 1、在运行的程序页面上面选中以下圈中按钮 2、点击上图2处,在界面上选中需要查看的按钮,或者文字等 3、点击界面上方第一个按钮“转为实时可视化树”,然后进入VS界面,查看左侧的树结构 4、在VS中的可视

    2024年02月15日
    浏览(35)
  • wpf数据绑定之元素、资源、后台绑定

            wpf前端的数据绑定主要分为元素、资源以及后台数据三种,元素可以简单的理解为前端的空间数据绑定,资源是在resource里找数据,而后台就是跟cs文件之间的数据互相传递。           先说下元素吧,也就是控件元素,因为代码比较简单,就不上效果了,自己可以

    2024年02月04日
    浏览(58)
  • WPF中TextBox使用KeyBinding绑定命令,键盘事件

        最近在做一个扫码枪识别条形码的功能,TextBox文本按回车键或者是扫码枪识别条形码自动触发查询功能,由于架构采用的是MVVM的开发模式,所以,刚开始采用KeyBinding的方式绑定命令,然后实现该功能;代码如下: 对应的ViewModel中绑定命令事件,代码如下所示     初步

    2024年02月14日
    浏览(51)
  • WPF容器的背景对鼠标事件的影响

    背景:在实现鼠标拖动窗口的过程中发现对父容器设置了鼠标拖动窗口的事件MouseLeftButtonDown 问题:非常困惑的是,竟然有的地方可以被点击拖动,但是有的却不行。 而且只有在设置了Background的这个地方是可以被点击拖动的 搜索了好一会发现确实是Background的问题 当控件(如

    2024年02月03日
    浏览(43)
  • WPF HALCON HSmartWindowControlWPF 鼠标绘制ROI

    更新:放出完整源码,供大家学习参考 yStack/SoupImgViewer (github.com) https://github.com/yStack/SoupImgViewer 0. 需求 在HSmartWindowsControlWPF上用鼠标绘制ROI,且显示绘制时的鼠标交互过程,最终效果如下: 1. 基本思路 在HSmartWindowControl上布置一层透明的Canvas,用于实时显示鼠标绘制ROI的过程

    2024年02月15日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包