WPF中的鼠标事件详解
当鼠标穿过一个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.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 overridevoid 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 overridevoid 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 overridevoid 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 overridevoid 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 overridevoid 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 overridevoid OnTextInput(TextCompositionEventArgs
{
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 overridevoid OnLostMouseCapture(MouseEventArgs e)
{
base.OnLostMouseCapture(e);
if (IsDrawing)
{
canvas.Children.Remove(elips);
IsDrawing = false;
}
}
protected overridevoid 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;
}
}
}
}
}
}
上面的程序中主要是绘制 移动图形以及图形自身大小的变化。这些只是2D图形的变化。
本文来自Wang_top的博客,原文地址:http://www.cnblogs.com/wangtaiping/archive/2011/04/04/2004971.html
杨航收集技术资料,分享给大家