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

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> &amp;&amp; e.OriginalSource.GetType() == <span style="color: #0000ff;">typeof</span>(Ellipse) &amp;&amp;<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,在一些鼠标与控件的交互处理上将会体现出很大的作用,因为在你捕获一个控件时,鼠标将无法再操作到其他控件,同时也不会受其他控件的影响

上一篇:HDU 1724 Ellipse (自适应辛普森积分)


下一篇:没有fillcolor,无法在python中绘制椭圆