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
楊航收集技術資料,分享給大家