wpf和winform不一样,wpf的mousemove和mousedown等等,都是在鼠标在控件内触发,鼠标移出控件即不触发,所以拖动控件的时候会出现bug,以下提供一种解决办法。
首先实例化一个Canvas布局:
<Canvas x:Name="c" MouseDown="c_MouseDown " MouseMove="c_MouseMove " MouseUp="c_MouseUp "></Canvas>
- public partial class Window1 : Window
- {
- private bool dragging;
- Point mousePoint;
- Rectangle shadow = new Rectangle();//显示控件阴影的矩形
- Control mouseCtrl = null;//被拖动的控件
- public Window1()
- {
- InitializeComponent();
- FullScreenManager.RepairWpfWindowFullScreenBehavior(this);
- dragging = false;
- shadow.Opacity = 0.5; //阴影加点透明度
- c.Children.Add(shadow);//阴影加入canvas
- shadow.Visibility = Visibility.Hidden ;//隐藏shadow
- }
- private void c_MouseDown(object sender, MouseButtonEventArgs e)
- {
- if (e.LeftButton == MouseButtonState.Pressed)
- {
- dragging = true;//标记鼠标按下
- mousePoint = e.GetPosition(this.c);//获取鼠标在但前canvas内的位置
- mouseCtrl = (Control)e.Source; //获得事件触发的源,即哪个控件
- VisualBrush v;
- v = new VisualBrush(mouseCtrl);//利用VisualBrush得到控件的影像
- shadow.Width = mouseCtrl.Width;
- shadow.Height = mouseCtrl.Height;
- shadow.Fill = v;//将影像填充给矩形
- Canvas.SetLeft(shadow, Canvas.GetLeft(mouseCtrl));
- Canvas.SetTop(shadow, Canvas.GetTop(mouseCtrl));
- shadow.Visibility = Visibility.Visible;//使矩形可见
- //Canvas.SetZIndex(shadow, 0);//可以通过SetZIndex设置阴影的z方向位置
- c.CaptureMouse();//强制捕获鼠标。这在对于背景透明的窗体里面是必须的
- }
- }
- private void c_MouseMove(object sender, MouseEventArgs e)
- {
- if (dragging)
- {
- if (e.LeftButton == MouseButtonState.Pressed)
- {
- Point theMousePoint = e.GetPosition(this.c);
- Canvas.SetLeft(shadow, theMousePoint.X - (mousePoint.X - Canvas.GetLeft(shadow)));
- Canvas.SetTop(shadow, theMousePoint.Y - (mousePoint.Y - Canvas.GetTop(shadow)));//简单的计算,只移动shadow
- mousePoint = theMousePoint;
- }
- }
- }
- private void c_MouseUp(object sender, MouseButtonEventArgs e)
- {
- dragging = false;
- Mouse.Capture(null);//取消强制捕获
- shadow.Visibility = Visibility.Hidden;//隐藏shadow
- Canvas.SetLeft(mouseCtrl , Canvas.GetLeft(shadow ));
- Canvas.SetTop(mouseCtrl , Canvas.GetTop(shadow ));//将控件放到新的位置
- }
- }
这里说明下,文章中的鼠标移动到透明背景窗体与鼠标移出控件是一样的原理,只要在mouseDown的时候强制捕获鼠标,UP的时候取消捕获即可。