https://www.cnblogs.com/xwlyun/archive/2012/09/12/2681585.html
本例实现了一个鼠标控制控件移动的简单例子,配合鼠标捕获达成预想效果:
1.新建一个wpf应用程序,为了演示效果,xaml简单修改如下:
[外链图片转存失败(img-MX71w8QX-1562046263308)(https://common.cnblogs.com/images/copycode.gif)]<Window x:Class="WpfApplication46.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Canvas x:Name="LayoutRoot" MouseLeftButtonDown="LayoutRoot_MouseLeftButtonDown" MouseLeftButtonUp="LayoutRoot_MouseLeftButtonUp" MouseMove="LayoutRoot_MouseMove"> <Ellipse Canvas.Left="30" Canvas.Top="30" Width="50" Height="50" Fill="Blue" /> <Ellipse Canvas.Left="100" Canvas.Top="100" Width="70" Height="70" Fill="Green" /> <Ellipse Canvas.Left="200" Canvas.Top="30" Width="90" Height="90" Fill="Yellow" /> </Canvas> </Window>![复制代码](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jb21tb24uY25ibG9ncy5jb20vaW1hZ2VzL2NvcHljb2RlLmdpZg)
共有三个圆(蓝、绿、黄),下面将要实现如何用鼠标拖动他们移动。
2.后台cs如下:
![复制代码](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jb21tb24uY25ibG9ncy5jb20vaW1hZ2VzL2NvcHljb2RlLmdpZg)/// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); }Point pBefore </span>= <span style="color: #0000ff;">new</span> Point();<span style="color: #008000;">//</span><span style="color: #008000;">鼠标点击前坐标</span> Point eBefore = <span style="color: #0000ff;">new</span> Point();<span style="color: #008000;">//</span><span style="color: #008000;">圆移动前坐标</span> <span style="color: #0000ff;">bool</span> isMove = <span style="color: #0000ff;">false</span>;<span style="color: #008000;">//</span><span style="color: #008000;">是否需要移动 </span><span style="color: #008000;">//</span><span style="color: #008000;">Root 鼠标左键按下事件</span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> LayoutRoot_MouseLeftButtonDown(<span style="color: #0000ff;">object</span><span style="color: #000000;"> sender, MouseButtonEventArgs e) { </span><span style="color: #0000ff;">if</span> (e.OriginalSource.GetType() == <span style="color: #0000ff;">typeof</span><span style="color: #000000;">(Ellipse)) { </span><span style="color: #0000ff;">this</span>.pBefore = e.GetPosition(<span style="color: #0000ff;">null</span>);<span style="color: #008000;">//</span><span style="color: #008000;">获取点击前鼠标坐标</span> Ellipse el =<span style="color: #000000;"> (Ellipse)e.OriginalSource; </span><span style="color: #0000ff;">this</span>.eBefore = <span style="color: #0000ff;">new</span> Point(Canvas.GetLeft(el), Canvas.GetTop(el));<span style="color: #008000;">//</span><span style="color: #008000;">获取点击前圆的坐标</span> isMove = <span style="color: #0000ff;">true</span>;<span style="color: #008000;">//</span><span style="color: #008000;">开始移动了</span> el.CaptureMouse();<span style="color: #008000;">//</span><span style="color: #008000;">鼠标捕获此圆</span>
}
}
</span><span style="color: #008000;">//</span><span style="color: #008000;">Root 鼠标左键放开事件</span>
<span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> LayoutRoot_MouseLeftButtonUp(<span style="color: #0000ff;">object</span><span style="color: #000000;"> sender, MouseButtonEventArgs e)
{
</span><span style="color: #0000ff;">if</span> (e.OriginalSource.GetType() == <span style="color: #0000ff;">typeof</span><span style="color: #000000;">(Ellipse))
{
Ellipse el </span>=<span style="color: #000000;"> (Ellipse)e.OriginalSource;
isMove </span>= <span style="color: #0000ff;">false</span>;<span style="color: #008000;">//</span><span style="color: #008000;">结束移动了</span>
el.ReleaseMouseCapture();<span style="color: #008000;">//</span><span style="color: #008000;">鼠标释放此圆</span>
}
}
</span><span style="color: #008000;">//</span><span style="color: #008000;">Root 鼠标移动事件</span>
<span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> LayoutRoot_MouseMove(<span style="color: #0000ff;">object</span><span style="color: #000000;"> sender, MouseEventArgs e)
{
</span><span style="color: #0000ff;">if</span> (e.OriginalSource != <span style="color: #0000ff;">null</span> && e.OriginalSource.GetType() == <span style="color: #0000ff;">typeof</span>(Ellipse) &&<span style="color: #000000;"> isMove)
{
Ellipse el </span>=<span style="color: #000000;"> (Ellipse)e.OriginalSource;
Point p </span>= e.GetPosition(<span style="color: #0000ff;">null</span>);<span style="color: #008000;">//</span><span style="color: #008000;">获取鼠标移动中的坐标</span>
Canvas.SetLeft(el, eBefore.X + (p.X -<span style="color: #000000;"> pBefore.X));
Canvas.SetTop(el, eBefore.Y </span>+ (p.Y -<span style="color: #000000;"> pBefore.Y));
}
}
}</span></pre>
![复制代码](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jb21tb24uY25ibG9ncy5jb20vaW1hZ2VzL2NvcHljb2RlLmdpZg)
因为不知道鼠标将会点击圆的哪一个部位,所以需要计算鼠标坐标pBefore,设置圆的坐标eBefore;
这里在鼠标左键按下点击圆的时候,设置了CaptureMouse,在鼠标松开左键时,设置ReleaseMouseCapture,试着注释掉这两行,观察程序运行的不同效果:
(1).移动其中一个圆,当碰到其他圆的时候:
设置了鼠标捕获的,移动中的圆将穿过其他圆而不造成影响;
没有设置鼠标捕获的,移动中的圆,碰到其他圆的时候,将会发生跳跃,变成移动其他的圆;
(2).移动圆至窗口边缘,甚至是窗口之外:
设置了鼠标捕获的,圆可以被移动到窗口之外;
没有设置鼠标捕获的,圆将被束缚在窗口之内;
可以试着只保留CaptureMouse,而注释掉ReleaseMouseCapture,鼠标在捕获圆之后将无法释放,你甚至将无法点击窗口左上角的关闭按钮;
鼠标捕获与释放CaptureMouse与ReleaseMouseCapture,在一些鼠标与控件的交互处理上将会体现出很大的作用,因为在你捕获一个控件时,鼠标将无法再操作到其他控件,同时也不会受其他控件的影响;