應用場景是這樣的,我須要拖動一個元素在屏幕上移動,註冊了被移動元素的MouseMove事件,可是當鼠標移到被移動元素的外面時,移動失效,且鼠標的手勢變成了普通的箭頭形狀,因而就找到了如下的解決方案。this
本例實現了一個鼠標控制控件移動的簡單例子,配合鼠標捕獲達成預想效果:xml
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" Height="350" Width="525">
<Canvas x:Name="LayoutRoot" MouseLeftButtonDown="LayoutRoot_MouseLeftButtonDown" MouseLeftButtonUp="LayoutRoot_MouseLeftButtonUp" MouseMove="LayoutRoot_MouseMove">
<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>ip
2.後臺cs以下it
/// <summary>
/// MainWindow.xaml 的交互邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}io
Point pBefore = new Point();//鼠標點擊前座標
Point eBefore = new Point();//圓移動前座標
bool isMove = false;//是否須要移動class
//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();//鼠標釋放此圓
}
}object
//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,在一些鼠標與控件的交互處理上將會體現出很大的做用,由於在你捕獲一個控件時,鼠標將沒法再操做到其餘控件,同時也不會受其餘控件的影響;