wpf鼠标捕获与控件交互——UIElement.CaptureMouse

摘要:
应用程序场景如下:我需要拖动一个元素在屏幕上移动,并注册要移动元素的MouseMove事件。但是,当鼠标移动到要移动的元素之外时,移动失败,鼠标手势将更改为常见的箭头形状。因此,找到了以下解决方案。此示例实现了一个简单的鼠标控制控件移动的示例,并通过鼠标捕获实现了所需的效果:1.创建一个新的wpf应用程序。为了演示效果,xaml简单地修改如下:总共有两个圆圈(绿色和黄色)。接下来,我们将实现如何使用鼠标拖动它们进行移动。

应用场景是这样的,我需要拖动一个元素在屏幕上移动,注册了被移动元素的MouseMove事件,但是当鼠标移到被移动元素的外面时,移动失效,且鼠标的手势变成了普通的箭头形状,于是就找到了以下的解决方案。

本例实现了一个鼠标控制控件移动的简单例子,配合鼠标捕获达成预想效果:

1.新建一个wpf应用程序,为了演示效果,xaml简单修改如下:共有两个圆(绿、黄),下面将要实现如何用鼠标拖动他们移动。

<Window x:Class="WpfApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Width="525">
  <Canvas x:Name="LayoutRoot" MouseLeftButtonDown="LayoutRoot_MouseLeftButtonDown" MouseLeftButtonUp="LayoutRoot_MouseLeftButtonUp" MouseMove="LayoutRoot_MouseMove"> 
    <Ellipse Canvas.Left="100" Canvas.Top="100" Fill="Green" />
    <Ellipse Canvas.Left="200" Canvas.Top="30" Fill="Yellow" />
  </Canvas>
</Window>

2.后台cs如下

/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();
  }

  Point pBefore = new Point();//鼠标点击前坐标
  Point eBefore = new Point();//圆移动前坐标
  bool isMove = false;//是否需要移动

  //Root 鼠标左键按下事件
  private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  {
    if (e.OriginalSource.GetType() == typeof(Ellipse))
    {
      this.pBefore = e.GetPosition(null);//获取点击前鼠标坐标
      Ellipse el = (Ellipse)e.OriginalSource;
      this.eBefore = new Point(Canvas.GetLeft(el), Canvas.GetTop(el));//获取点击前圆的坐标
      isMove = true;//开始移动了
      el.CaptureMouse();//鼠标捕获此圆
    }
  }

  //Root 鼠标左键放开事件
  private void LayoutRoot_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
  {
    if (e.OriginalSource.GetType() == typeof(Ellipse))
    {
      Ellipse el = (Ellipse)e.OriginalSource;
      isMove = false;//结束移动了
      el.ReleaseMouseCapture();//鼠标释放此圆
    }
  }

  //Root 鼠标移动事件
  private void LayoutRoot_MouseMove(object sender, MouseEventArgs e)
  {
    if (e.OriginalSource != null && e.OriginalSource.GetType() == typeof(Ellipse) && isMove)
    {
      Ellipse el = (Ellipse)e.OriginalSource;
      Point p = e.GetPosition(null);//获取鼠标移动中的坐标
      Canvas.SetLeft(el, eBefore.X + (p.X - pBefore.X));
      Canvas.SetTop(el, eBefore.Y + (p.Y - pBefore.Y));
    }
  }

}

因为不知道鼠标将会点击圆的哪一个部位,所以需要计算鼠标坐标pBefore,设置圆的坐标eBefore;
这里在鼠标左键按下点击圆的时候,设置了CaptureMouse,在鼠标松开左键时,设置ReleaseMouseCapture,试着注释掉这两行,观察程序运行的不同效果:

(1).移动其中一个圆,当碰到其他圆的时候:

设置了鼠标捕获的,移动中的圆将穿过其他圆而不造成影响;

没有设置鼠标捕获的,移动中的圆,碰到其他圆的时候,将会发生跳跃,变成移动其他的圆;

(2).移动圆至窗口边缘,甚至是窗口之外:

设置了鼠标捕获的,圆可以被移动到窗口之外;

没有设置鼠标捕获的,圆将被束缚在窗口之内;

可以试着只保留CaptureMouse,而注释掉ReleaseMouseCapture,鼠标在捕获圆之后将无法释放,你甚至将无法点击窗口左上角的关闭按钮;

鼠标捕获与释放CaptureMouse与ReleaseMouseCapture,在一些鼠标与控件的交互处理上将会体现出很大的作用,因为在你捕获一个控件时,鼠标将无法再操作到其他控件,同时也不会受其他控件的影响

免责声明:文章转载自《wpf鼠标捕获与控件交互——UIElement.CaptureMouse》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇数值分析笔记(0)——数值分析研究的对象和内容java实现的MySQL自动备份和还原(struts2+Hibernate)---兼容 window+Linux下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

WPF程序性能优化总结

原文链接:https://blog.csdn.net/u010265681/article/details/77571947 WPF程序性能由很多因素造成,以下是简单地总结: 元素: 1、 减少需要显示的元素数量:去除不需要或者冗余的XAML元素代码. 通过移出不必要的元素,合并layout panels,简化templates来减少可视化树的层次。这可以...

WPF委托实现方法回调(刷新父窗体)

MainWindow.xaml(父窗体) <StackPanel> <Label Content="{Binding Message}"/> <Button Content="Input User Name" Command="{Binding OpenSubWindowCommand}"/> </...

WPF 自定义TextBox,可控制键盘输入内容

非原创,整理之前的代码的时候找出来的,可用,与大家分享一下! 1 public class NumbericBoxWithZero : NumericBox 2 { 3 public NumbericBoxWithZero() 4 : base() 5 { 6...

WPF 右上角带数字的按钮

效果如图所示   三种方案, 1:不改控件模版,布局实现,死开 2:改button模版,利用附加属性,附加附加属性,功能多了话,不利于拓展 3:继承button,添加依赖属性,接下来是这种 1:新建类 为啥交LBSButton,因为是我帅帅的名字啊, 问我为啥截图?因为方便啊,反正代码等会也会放下面 让我们添加一个属性啊,右上角信息的内容,我这里直接用...

将 UWP 的有效像素(Effective Pixels)引入 WPF

在很久很久以前,WPF 诞生之初,有一个神奇的单位,它的名字叫做——设备无关单位(DIP,Device Independent Unit)。微软给它描绘了一片美好的愿景——在任何显示器上显示的尺寸是相同的。 What the ** is this unit!!! 神 TM 相同!!! UWP 采用有效像素(Effective Pixels)来描述尺寸,这是...

wpf图片查看器,支持鼠标滚动缩放拖拽

最近项目需要,要用到一个图片查看器,类似于windows自带的图片查看器那样,鼠标滚动可以缩放,可以拖拽图片,于是就写了这个简单的图片查看器。 前台代码: <Window x:Class="PictureViewer.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/...