WPF中的鼠标事件详解

 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事件的处理器,做一些必要的收尾工作。下面我们写一个小程序来使用这些事件:

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的框选元素,你可以使用鼠标事件和适当的布局面板。下面是一种常见的实现方式: 1. 在XAML创建一个包含需要框选的元素的布局面板,例如Grid或Canvas。 2. 添加鼠标事件处理程序。在Grid或Canvas上订阅MouseLeftButtonDown、MouseLeftButtonUp和MouseMove事件。 3. 在MouseLeftButtonDown事件处理程序,记录下鼠标按下的位置作为起始点。 4. 在MouseMove事件处理程序,获取当前鼠标位置,并计算出框选区域的大小和位置。可以使用Mouse.GetPosition方法获取鼠标相对于Grid或Canvas的位置。 5. 更新框选区域的位置和大小。可以使用一个矩形元素或者一个透明的选择框元素来表示框选区域。 6. 在MouseLeftButtonUp事件处理程序,完成框选操作。可以根据框选区域和元素的位置关系来确定被选的元素。 以下是一个简单的示例,演示了如何在WPF实现框选元素: ```xaml <Grid MouseLeftButtonDown="OnMouseLeftButtonDown" MouseMove="OnMouseMove" MouseLeftButtonUp="OnMouseLeftButtonUp"> <Rectangle x:Name="SelectionBox" Stroke="Red" StrokeThickness="1" Fill="#80FF0000" Visibility="Collapsed"/> <Rectangle Width="50" Height="50" Fill="Blue"/> <Rectangle Width="50" Height="50" Fill="Green" Margin="70,0,0,0"/> <Rectangle Width="50" Height="50" Fill="Yellow" Margin="140,0,0,0"/> </Grid> ``` ```csharp private Point startPoint; private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { startPoint = e.GetPosition((UIElement)sender); } private void OnMouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { Point currentPoint = e.GetPosition((UIElement)sender); double minX = Math.Min(startPoint.X, currentPoint.X); double minY = Math.Min(startPoint.Y, currentPoint.Y); double maxX = Math.Max(startPoint.X, currentPoint.X); double maxY = Math.Max(startPoint.Y, currentPoint.Y); SelectionBox.Margin = new Thickness(minX, minY, 0, 0); SelectionBox.Width = maxX - minX; SelectionBox.Height = maxY - minY; SelectionBox.Visibility = Visibility.Visible; } } private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { SelectionBox.Visibility = Visibility.Collapsed; // 根据框选区域和元素位置判断被选的元素 foreach (UIElement element in ((Grid)sender).Children) { if (element is Rectangle rect) { Rect elementRect = new Rect(element.TransformToAncestor((Grid)sender).Transform(new Point(0, 0)), new Size(rect.Width, rect.Height)); if (elementRect.IntersectsWith(new Rect(startPoint, e.GetPosition((UIElement)sender)))) { // 处理被选的元素 // ... } } } } ``` 在这个示例,我们使用一个Grid作为布局面板,并在其添加了几个Rectangle元素作为可选元素。通过鼠标事件处理程序,我们可以实现框选元素的功能。在MouseLeftButtonUp事件处理程序,我们可以根据框选区域和元素位置的关系来确定被选的元素,并进行相应的处理。 希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值