WPF中鼠标/键盘/拖拽事件及用行为封装事件的方法是什么(wpf,开发技术)

时间:2024-04-29 20:12:06 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

Windows中的事件通过消息机制来完成,也就是Windows系统来捕获用户输入(如鼠标点击、键盘输入),然后Windows发送一个消息给应用程序,应用程序进行具体的处理。在Winform中,窗体中每个控件都是有独立的句柄,也就是每个控件都可以收到Windows系统传来的消息,但是在WPF中,窗体中的控件是没有句柄的,所以只能是窗体进行消息捕获,WPF框架经过处理再传递给相应的控件。这是WPF和Winform在事件处理上的不同之处。

鼠标事件

常用的鼠标事件包括:

MouseEnter、MouseLeave、MouseDown、MouseUp、MouseMove、MouseLeftButtonDown、MouseLeftButtonUp、MouseRightButtonDown、MouseRightButtonUp、MouseDoubleClick

值得注意的是诸如Button一类的控件,具有Click事件,它其实是仍然是调用了MouseLeftButtonDown等底层事件,然后进行截断,也就是说Button控件只能调用Click事件而不能调用MouseLeftButtonDown事件,因为在Click事件中,调用了MouseLeftButtonDown事件,而且应用了e.Handled = true;阻止事件向下传下去。如果要在Click事件之前进行事件处理,则可以使用PreviewMouseLeftButtonDown事件。

键盘输入事件

用的最多的键盘输入事件有:

KeyDown、KeyUp、TextInput

如果要对某个键进行处理则可以

privatevoidTextBox_KeyDown(objectsender,KeyEventArgse){if(e.Key==Key.Enter){//e.Handled=true;//表示已经处理完成//具体逻辑}}

注意TextBox是不能捕获到TextInput事件的,只能捕获到KeyDown、TextChanged等事件,但也可以捕获到PreviewTextInput事件,事件捕获顺序是KeyDown-PreviewTextInput-TextChanged

案例:做一个搜索栏,输入文字后回车搜索

实现方式1:可以在TextBox上增加KeyDown事件,捕获Key.Enter键。

实现方式2:增加一个Button按钮,设置<Button Content="搜索" IsDefault="True"/>

拖拽事件

拖拽事件包括:Drop、DragLeave、DragOver、DragEnter事件

案例,将某个控件拖拽到另一个区域

WPF中鼠标/键盘/拖拽事件及用行为封装事件的方法是什么

界面XAML

<Grid><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><StackPanelx:Name="panel"Background="#F7F9FA"><BorderBackground="Orange"Height="30"Width="30"MouseLeftButtonDown="Border_MouseLeftButtonDown"/></StackPanel><!--必须设置Background,否则默认为null,null是没有背景和Transparent不同--><!--AllowDrop="True"必须设置--><Canvasx:Name="canvas"Grid.Column="1"Drop="Canvas_Drop"AllowDrop="True"Background="Transparent"></Canvas></Grid>

实现代码

privatevoidCanvas_Drop(objectsender,DragEventArgse){vardata=e.Data.GetData(typeof(Border));//canvas.Children.Add(data);//直接这样不可以,因为同一个实例不允许在于两个容器中//先在之前的容器中移除,再添加panel.Children.Remove(dataasUIElement);canvas.Children.Add(dataasUIElement);//获得鼠标相对于canvas的位置varpoint=e.GetPosition((Canvas)sender);Canvas.SetLeft(dataasUIElement,point.X);Canvas.SetTop(dataasUIElement,point.Y);}privatevoidBorder_MouseLeftButtonDown(objectsender,MouseButtonEventArgse){Borderborder=senderasBorder;DragDrop.DoDragDrop(border,border,DragDropEffects.Copy);}

用行为封装事件

通过一个案例来讲解

案例,实现某个控件的随意拖动

WPF中鼠标/键盘/拖拽事件及用行为封装事件的方法是什么

用事件来实现

主要是通过MouseLeftButtonDown、MouseLeftButtonUp和MouseMove三个事件来实现

XAML界面

<Canvas><BorderBackground="Orange"Width="100"Height="50"Canvas.Left="100"Canvas.Top="100"MouseLeftButtonDown="Border_MouseLeftButtonDown"MouseLeftButtonUp="Border_MouseLeftButtonUp"MouseMove="Border_MouseMove"/></Canvas>

实现代码

privateCanvas_parentCanvas=null;privatebool_isDragging=false;privatePoint_mouseCurrentPoint;privatevoidBorder_MouseLeftButtonDown(objectsender,MouseButtonEventArgse){//获得承载Border的父对象if(_parentCanvas==null)_parentCanvas=(Canvas)VisualTreeHelper.GetParent(senderasBorder);this._isDragging=true;//获得相对于border的坐标this._mouseCurrentPoint=e.GetPosition(senderasBorder);//关键,锁定鼠标即不让鼠标选中其他元素(senderasBorder).CaptureMouse();}privatevoidBorder_MouseLeftButtonUp(objectsender,MouseButtonEventArgse){if(_isDragging){//关键,取消锁定鼠标(senderasBorder).ReleaseMouseCapture();_isDragging=false;}}privatevoidBorder_MouseMove(objectsender,MouseEventArgse){if(_isDragging){//获得相对于Canvas的坐标Pointpoint=e.GetPosition(_parentCanvas);(senderasBorder).SetValue(Canvas.TopProperty,point.Y-_mouseCurrentPoint.Y);(senderasBorder).SetValue(Canvas.LeftProperty,point.X-_mouseCurrentPoint.X);}}

关键点

在进行移动的时候,一定要锁定鼠标,也就是不让鼠标可以选中其他元素,如果不锁定会出现以下情况:

情况1:如果鼠标移动过快,会出现图形不能跟随的情况

WPF中鼠标/键盘/拖拽事件及用行为封装事件的方法是什么

情况2:如果有多个元素,会出现选中其他元素的情况

下图演示中,鼠标箭头未松开

WPF中鼠标/键盘/拖拽事件及用行为封装事件的方法是什么

锁定鼠标有两种方式

(senderasBorder).CaptureMouse()//锁定(senderasBorder).ReleaseMouseCapture();//解锁System.Windows.Input.Mouse.Capture(senderasBorder);//锁定System.Windows.Input.Mouse.Capture(null);//解锁

用行为来封装

上文中主要是通过MouseLeftButtonDown、MouseLeftButtonUp和MouseMove三个事件来实现,在XAML中需要对这三个事件进行绑定。行为则可以将这三个事件封装在一起。

  • 使用行为需要nuget安装Microsoft.Xaml.Behaviors.Wpf,FrameWork版本安装System.Windows.Interactivity.WPF

  • 新建一个类,继承自Behavior<T>,类中重写OnAttached()和OnDetaching()方法。

OnAttached()表示当挂载到对应的对象上的时候触发

OnDetaching()在对象销毁时触发

publicclassDragMoveBehavior:Behavior<Border>{//当挂载到对应的对象上的时候触发protectedoverridevoidOnAttached(){base.OnAttached(); //方法与上面相同//this.AssociatedObject表示关联的对象this.AssociatedObject.MouseLeftButtonDown+=AssociatedObject_MouseLeftButtonDown;this.AssociatedObject.MouseLeftButtonUp+=AssociatedObject_MouseLeftButtonUp;this.AssociatedObject.MouseMove+=AssociatedObject_MouseMove;}privateCanvas_parentCanvas=null;privatebool_isDragging=false;privatePoint_mouseCurrentPoint;privatevoidAssociatedObject_MouseMove(objectsender,System.Windows.Input.MouseEventArgse){if(_isDragging){//相对于Canvas的坐标Pointpoint=e.GetPosition(_parentCanvas);//设置最新坐标this.AssociatedObject.SetValue(Canvas.TopProperty,point.Y-_mouseCurrentPoint.Y);this.AssociatedObject.SetValue(Canvas.LeftProperty,point.X-_mouseCurrentPoint.X);}}privatevoidAssociatedObject_MouseLeftButtonUp(objectsender,System.Windows.Input.MouseButtonEventArgse){if(_isDragging){//释放鼠标锁定//this.AssociatedObject.ReleaseMouseCapture();System.Windows.Input.Mouse.Capture(null);_isDragging=false;}}privatevoidAssociatedObject_MouseLeftButtonDown(objectsender,System.Windows.Input.MouseButtonEventArgse){this._isDragging=true;//Canvasif(_parentCanvas==null)_parentCanvas=(Canvas)VisualTreeHelper.GetParent(senderasBorder);//当前鼠标坐标this._mouseCurrentPoint=e.GetPosition(senderasBorder);//鼠标锁定//this.AssociatedObject.CaptureMouse();System.Windows.Input.Mouse.Capture(this.AssociatedObject);}//对象销毁protectedoverridevoidOnDetaching(){this.AssociatedObject.MouseLeftButtonDown-=AssociatedObject_MouseLeftButtonDown;this.AssociatedObject.MouseLeftButtonUp-=AssociatedObject_MouseLeftButtonUp;this.AssociatedObject.MouseMove-=AssociatedObject_MouseMove;}}

XAML中代码

<Canvas><BorderBackground="Orange"Width="100"Height="50"Canvas.Left="100"Canvas.Top="100"><i:Interaction.Behaviors><local:DragMoveBehavior/></i:Interaction.Behaviors></Border></Canvas>
 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:WPF中鼠标/键盘/拖拽事件及用行为封装事件的方法是什么的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:WPF中的APP生命周期及全局异常捕获源码分析下一篇:

12 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18