WPF中的鼠标事件详解
WPF中的鼠標(biāo)事件詳解
Uielement和ContentElement都定義了十個(gè)以Mouse開頭的事件,8個(gè)以PreviewMouse開頭的事件,MouseMove,PreviewMouseMove,MouseEnter,Mouseleave的事件處理器類型都是MouseEventHandler類型。這些事件都具備對應(yīng)得MouseEventargs對象。(沒有pre的enter和leave)。當(dāng)鼠標(biāo)穿過一個(gè)Element時(shí),mousemove會發(fā)生很多次,但是mouseenter和mouseleave只會發(fā)生一次,分別在鼠標(biāo)進(jìn)入element區(qū)域以及離開element區(qū)域是發(fā)生。
UIElement和ContentElement定義了兩個(gè)只讀屬性,ISmouseOver:如果鼠標(biāo)在Element上,這個(gè)屬性為true,如果鼠標(biāo)不僅在這個(gè)Element上,且不在其任何子控件上,那么IsMouseDirectOver也為true。
當(dāng)處理MouseMove ,MouseEnter,Mouseleave事件時(shí)我們還可以獲取正在按下的鼠標(biāo)按鍵式哪一個(gè):Leftbutton,middlebutton,RightButton,以及兩個(gè)擴(kuò)充按鍵XButton1和XButton2。(這五個(gè)都是MouseEventargs的屬性),他門的值是MouseButtonState枚舉的一個(gè),只有兩種狀態(tài),Pressed和Released.
對于MouseMove事件,你還有可能想要獲取當(dāng)前鼠標(biāo)的位置,可以使用MouseEventargs的GetPostion方法。通過事件的MouseEventargs的ChangeButton屬性可以得知是哪個(gè)鼠標(biāo)按鈕被按下。
MouseWheel和PreviewWheel事件,主要是處理鼠標(biāo)滾輪事件,MousewheelEventargs有一個(gè)屬性Delta屬性,它記錄鼠標(biāo)滾輪的刻度,現(xiàn)在的鼠標(biāo)每滾一下刻度是120,轉(zhuǎn)向用戶的時(shí)候就是-120.可以利用systemprarameters。IsMouseWheelPresent得知鼠標(biāo)是否有滾輪。
Mouse類的靜態(tài)方法也可以獲取鼠標(biāo)的位置和狀態(tài),也具有靜態(tài)方法可以添加或刪除鼠標(biāo)事件處理器。MouseDevice類有一些實(shí)例方法可以用來獲取鼠標(biāo)位置和按鈕狀態(tài)。
鼠標(biāo)在屏幕上使用一個(gè)小小的位圖來顯示的,此圖標(biāo)稱作鼠標(biāo)光標(biāo),在Wpf中,光標(biāo)就是Cursor類型的對象,可以將Cursor對象設(shè)置到FrameworkElement的Cursor屬性,就可以將指定的鼠標(biāo)圖標(biāo)關(guān)聯(lián)到某個(gè)element,當(dāng)然你也可以重載onQueryCursor方法或者給QueryCursor事件添加處理器,鼠標(biāo)移動就會觸發(fā)這個(gè)事件,QueryCursorEventargs伴隨這個(gè)事件,他有一個(gè)Cursor屬性,可以供我們使用。
捕獲鼠標(biāo):在我們鼠標(biāo)按下后一旦鼠標(biāo)移出element的區(qū)域,就收不到鼠標(biāo)事件了,但是有時(shí)候這個(gè)并不是我們想要的結(jié)果,所有需要在鼠標(biāo)進(jìn)入這個(gè)了element的時(shí)候獲取鼠標(biāo),這樣鼠標(biāo)就算離開了這個(gè)區(qū)域也會獲取到鼠標(biāo)消息。UIelement和contentelement都定義了CaputerMouse方法,Mouse類也提供了Caputer靜態(tài)方法,讓我們可以捕獲鼠標(biāo),一旦捕獲成功就會返回true,在我們的事件處理完成后應(yīng)該釋放這個(gè)捕獲,使用ReleaseMouseCaputer.
如果使用了鼠標(biāo)捕獲,就必須安裝LostmouseCaputer事件的處理器,做一些必要的收尾工作。下面我們寫一個(gè)小程序來使用這些事件:
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 overridevoid OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
if (IsDragging)
{
return;
}
//創(chuàng)建一個(gè)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);
//獲取鼠標(biāo)
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;
}
//得到點(diǎn)擊的事件 為未來做準(zhǔn)備
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 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 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)
{//如果當(dāng)前有選定的元素就只將當(dāng)前元素的大小變化
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
楊航收集技術(shù)資料,分享給大家
總結(jié)
以上是生活随笔為你收集整理的WPF中的鼠标事件详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BitmapEffect位图效果是简单的
- 下一篇: 理解Windows窗体和WPF中的跨线程