WPF中的鼠标事件详解
2011-10-27 09:44
447 查看
Uielement和ContentElement都定义了十个以Mouse开头的事件,8个以PreviewMouse开头的事件,MouseMove,PreviewMouseMove,MouseEnter,Mouseleave的事件处理器类型都是MouseEventHandler类型。这些事件都具备对应得MouseEventargs对象。(没有pre的enter和leave)。
当鼠标穿过一个Element时,mousemove会发生很多次,但是mouseenter和mouseleave只会发生一次,分别在鼠标进入element区域以及离开element区域是发生。
UIElement和ContentElement定义了两个只读属性,ISmouseOver:如果鼠标在Element上,这个属性为true,如果鼠标不仅在这个Element上,且不在其任何子控件上,那么IsMouseDirectOver也为true。
当处理MouseMove ,MouseEnter,Mouseleave事件时我们还可以获取正在按下的鼠标按键式哪一个:Leftbutton,middlebutton,RightButton,以及两个扩充按键XButton1和XButton2。(这五个都是MouseEventargs的属性),他门的值是MouseButtonState枚举的一个,只有两种状态,Pressed和Released.
对于MouseMove事件,你还有可能想要获取当前鼠标的位置,可以使用MouseEventargs的GetPostion方法。通过事件的MouseEventargs的ChangeButton属性可以得知是哪个鼠标按钮被按下。
MouseWheel和PreviewWheel事件,主要是处理鼠标滚轮事件,MousewheelEventargs有一个属性Delta属性,它记录鼠标滚轮的刻度,现在的鼠标每滚一下刻度是120,转向用户的时候就是-120.可以利用systemprarameters。IsMouseWheelPresent得知鼠标是否有滚轮。
Mouse类的静态方法也可以获取鼠标的位置和状态,也具有静态方法可以添加或删除鼠标事件处理器。MouseDevice类有一些实例方法可以用来获取鼠标位置和按钮状态。
鼠标在屏幕上使用一个小小的位图来显示的,此图标称作鼠标光标,在Wpf中,光标就是Cursor类型的对象,可以将Cursor对象设置到FrameworkElement的Cursor属性,就可以将指定的鼠标图标关联到某个element,当然你也可以重载onQueryCursor方法或者给QueryCursor事件添加处理器,鼠标移动就会触发这个事件,QueryCursorEventargs伴随这个事件,他有一个Cursor属性,可以供我们使用。
捕获鼠标:在我们鼠标按下后一旦鼠标移出element的区域,就收不到鼠标事件了,但是有时候这个并不是我们想要的结果,所有需要在鼠标进入这个了element的时候获取鼠标,这样鼠标就算离开了这个区域也会获取到鼠标消息。UIelement和contentelement都定义了CaputerMouse方法,Mouse类也提供了Caputer静态方法,让我们可以捕获鼠标,一旦捕获成功就会返回true,在我们的事件处理完成后应该释放这个捕获,使用ReleaseMouseCaputer.
如果使用了鼠标捕获,就必须安装LostmouseCaputer事件的处理器,做一些必要的收尾工作。下面我们写一个小程序来使用这些事件:
当鼠标穿过一个Element时,mousemove会发生很多次,但是mouseenter和mouseleave只会发生一次,分别在鼠标进入element区域以及离开element区域是发生。
UIElement和ContentElement定义了两个只读属性,ISmouseOver:如果鼠标在Element上,这个属性为true,如果鼠标不仅在这个Element上,且不在其任何子控件上,那么IsMouseDirectOver也为true。
当处理MouseMove ,MouseEnter,Mouseleave事件时我们还可以获取正在按下的鼠标按键式哪一个:Leftbutton,middlebutton,RightButton,以及两个扩充按键XButton1和XButton2。(这五个都是MouseEventargs的属性),他门的值是MouseButtonState枚举的一个,只有两种状态,Pressed和Released.
对于MouseMove事件,你还有可能想要获取当前鼠标的位置,可以使用MouseEventargs的GetPostion方法。通过事件的MouseEventargs的ChangeButton属性可以得知是哪个鼠标按钮被按下。
MouseWheel和PreviewWheel事件,主要是处理鼠标滚轮事件,MousewheelEventargs有一个属性Delta属性,它记录鼠标滚轮的刻度,现在的鼠标每滚一下刻度是120,转向用户的时候就是-120.可以利用systemprarameters。IsMouseWheelPresent得知鼠标是否有滚轮。
Mouse类的静态方法也可以获取鼠标的位置和状态,也具有静态方法可以添加或删除鼠标事件处理器。MouseDevice类有一些实例方法可以用来获取鼠标位置和按钮状态。
鼠标在屏幕上使用一个小小的位图来显示的,此图标称作鼠标光标,在Wpf中,光标就是Cursor类型的对象,可以将Cursor对象设置到FrameworkElement的Cursor属性,就可以将指定的鼠标图标关联到某个element,当然你也可以重载onQueryCursor方法或者给QueryCursor事件添加处理器,鼠标移动就会触发这个事件,QueryCursorEventargs伴随这个事件,他有一个Cursor属性,可以供我们使用。
捕获鼠标:在我们鼠标按下后一旦鼠标移出element的区域,就收不到鼠标事件了,但是有时候这个并不是我们想要的结果,所有需要在鼠标进入这个了element的时候获取鼠标,这样鼠标就算离开了这个区域也会获取到鼠标消息。UIelement和contentelement都定义了CaputerMouse方法,Mouse类也提供了Caputer静态方法,让我们可以捕获鼠标,一旦捕获成功就会返回true,在我们的事件处理完成后应该释放这个捕获,使用ReleaseMouseCaputer.
如果使用了鼠标捕获,就必须安装LostmouseCaputer事件的处理器,做一些必要的收尾工作。下面我们写一个小程序来使用这些事件:
using System; using System.Windows; using System.Windows.Input; using System.Windows.Controls; using System.Windows.Shapes; using System.Windows.Media; namespace WPFDemo { class DrawCircles : Window { Canvas canvas; Boolean IsDrawing; Ellipse elips; Point ptcenter; Boolean IsDragging; Boolean IsChanging; FrameworkElement elDragging; Ellipse ChangeElips; Point ptmousestart, ptElementStart; [STAThread] static void Main() { Application app = new Application(); app.Run(new DrawCircles()); } public DrawCircles() { Title = "Draw Circles"; Content = canvas = new Canvas(); Line line = new Line(); line.Width = 1; line.X1 = 0; line.X2 = canvas.ActualWidth/2; line.Y1 = canvas.ActualHeight / 2; line.Y2 = 0; canvas.Children.Add(line); line.Stroke = SystemColors.WindowTextBrush; } protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); if (IsDragging) { return; } //创建一个Ellipse对象,并且把它加入到Canvas中 ptcenter = e.GetPosition(canvas); elips = new Ellipse(); elips.Stroke = SystemColors.WindowTextBrush; //elips.StrokeThickness = 0.1; elips.Width = 0; elips.Height = 0; elips.MouseEnter += new MouseEventHandler(elips_MouseEnter); elips.MouseLeave += new MouseEventHandler(elips_MouseLeave); canvas.Children.Add(elips); Canvas.SetLeft(elips, ptcenter.X); Canvas.SetTop(elips, ptcenter.Y); //获取鼠标 CaptureMouse(); IsDrawing = true; } void elips_MouseLeave(object sender, MouseEventArgs e) { ChangeElips = sender as Ellipse; ChangeElips.Stroke = SystemColors.WindowTextBrush; ChangeElips = null; if ( IsChanging) { IsChanging = false; } //throw new NotImplementedException(); } void elips_MouseEnter(object sender, MouseEventArgs e) { ChangeElips = sender as Ellipse; ChangeElips.Stroke = SystemColors.WindowFrameBrush; IsChanging = true; //throw new NotImplementedException(); } protected override void OnMouseRightButtonDown(MouseButtonEventArgs e) { base.OnMouseRightButtonDown(e); if (IsDrawing) { return; } //得到点击的事件 为未来做准备 ptmousestart = e.GetPosition(canvas); elDragging = canvas.InputHitTest(ptmousestart) as FrameworkElement; if (elDragging != null) { ptElementStart = new Point(Canvas.GetLeft(elDragging), Canvas.GetTop(elDragging)); IsDragging = true; } } protected override void OnMouseDown(MouseButtonEventArgs e) { base.OnMouseDown(e); if (e.ChangedButton == MouseButton.Middle) { Shape shape = canvas.InputHitTest(e.GetPosition(canvas)) as Shape; if (shape != null) { shape.Fill = (shape.Fill == Brushes.Red ? Brushes.Transparent : Brushes.Red); } } } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); Point ptmouse = e.GetPosition(canvas); if (IsDrawing) { double draddius = Math.Sqrt(Math.Pow(ptcenter.X - ptmouse.X, 2) + Math.Pow(ptcenter.Y - ptmouse.Y, 2)); Canvas.SetLeft(elips, ptcenter.X - draddius); Canvas.SetTop(elips, ptcenter.Y - draddius); elips.Width = 2 * draddius; elips.Height = 2 * draddius; } //移动椭圆 else if (IsDragging) { Canvas.SetLeft(elDragging, ptElementStart.X + ptmouse.X - ptmousestart.X); Canvas.SetTop(elDragging, ptElementStart.Y + ptmouse.Y - ptmousestart.Y); } } protected override void OnMouseUp(MouseButtonEventArgs e) { base.OnMouseUp(e); if (IsDrawing&&e.ChangedButton == MouseButton.Left) { elips.Stroke = Brushes.Blue; elips.StrokeThickness =elips.Width/8; elips.Fill = Brushes.Red; IsDrawing = false; ReleaseMouseCapture(); } else if (IsDragging&&e.ChangedButton == MouseButton.Right) { IsDragging = false; } } protected override void OnTextInput(TextCompositionEventArgs e) { base.OnTextInput(e); if (e.Text.IndexOf('/x18')!=-1) { if (IsDrawing) { ReleaseMouseCapture(); } else if (IsDragging) { Canvas.SetLeft(elDragging, ptElementStart.X); Canvas.SetTop(elDragging, ptElementStart.Y); IsDragging = false; } } } protected override void OnLostMouseCapture(MouseEventArgs e) { base.OnLostMouseCapture(e); if (IsDrawing) { canvas.Children.Remove(elips); IsDrawing = false; } } protected override void OnMouseWheel(MouseWheelEventArgs e) { base.OnMouseWheel(e); if (IsChanging &&ChangeElips!=null) {//如果当前有选定的元素 就只将当前元素的大小变化 Point pt = new Point(Canvas.GetLeft(ChangeElips) + ChangeElips.Width / 2, Canvas.GetTop(ChangeElips) + ChangeElips.Height / 2); double draddius = (e.Delta*1.0 / 1200 + 1) * ChangeElips.Height; Canvas.SetLeft(ChangeElips, pt.X - draddius/2); Canvas.SetTop(ChangeElips, pt.Y - draddius/2); ChangeElips.Height = draddius; ChangeElips.Width = draddius; } else if (ChangeElips==null) {//如果没有选定的元素 就所有的元素一起变化大小 double canvax = canvas.ActualWidth; double canvay = canvas.ActualHeight; foreach (UIElement elisp in canvas.Children) { Ellipse els = elisp as Ellipse; if (els!=null) { double draddius = (e.Delta * 1.0 / 1200 + 1) * els.Height; double x1 = Canvas.GetLeft(els); double y1 = Canvas.GetTop(els); double draddiusx = (e.Delta * 1.0 / 1200) * (x1 - canvax / 2) + x1; double draddiusY = (e.Delta * 1.0 / 1200) * (y1 - canvay / 2) + y1; Canvas.SetLeft(els,draddiusx); Canvas.SetTop(els,draddiusY); els.Height = draddius; els.Width = draddius; els.StrokeThickness = els.Width /8; } } } } } }
相关文章推荐
- 跟着小王学习wpf之十二 Wpf中的鼠标事件详解
- WPF中的鼠标事件详解
- 鼠标事件的screenY,pageY,clientY,layerY,offsetY属性详解
- js中鼠标滚轮事件详解
- JavaScript事件类型中焦点、鼠标和滚轮事件详解
- opencv2+ 鼠标事件详解及示例代码
- js鼠标滚轮事件详解(全兼容ie、chrome、firefox)实现图片缩放
- 以JTextPanel为例Swing的鼠标事件详解
- JavaScript鼠标事件onmousedown,onmousemove,onmouseout,onmouseover,onmouseup的用法和区别详解
- js中鼠标滚轮事件详解
- WPF 之 鼠标双击事件
- window.event 对象详解 以及鼠标 组合按键的响应事件
- JavaScript焦点事件、鼠标事件和滚轮事件使用详解
- javascript鼠标滚动事件详解及应用
- WPF/E CTP Quick Start - 第十部分:脚本和鼠标事件(翻译)
- wpf 元素如果设置背景透明,则无法接收鼠标事件
- 在WPF中强制捕获鼠标,鼠标移出控件后依然何以获取鼠标事件
- WPF/E CTP Quick Start - 第十部分:脚本和鼠标事件(翻译)
- WPF之鼠标事件
- 【WPF】【MVVM】把鼠标事件写到Controller层