wpf鼠標捕獲與控件交互——UIElement.CaptureMouse


本例實現了一個鼠標控制控件移動的簡單例子,配合鼠標捕獲達成預想效果:


1.新建一個wpf應用程序,為了演示效果,xaml簡單修改如下:

<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>

共有三個圓(藍、綠、黃),下面將要實現如何用鼠標拖動他們移動


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,在一些鼠標與控件的交互處理上將會體現出很大的作用,因為在你捕獲一個控件時,鼠標將無法再操作到其他控件,同時也不會受其他控件的影響


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM