2011-06-08 69 views
7

创建移动用户控件拖动WPF用户控制

<UserControl x:Class="Restaurant.Views.Managerer.TablePanel" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:Restaurant.Helpers.Converter" 
     mc:Ignorable="d" 
     x:Name="root" 
     MouseLeftButtonDown="root_MouseLeftButtonDown" 
     MouseLeftButtonUp="root_MouseLeftButtonUp" 
     MouseMove="root_MouseMove"  
     DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
.... 

代码

Point anchorPoint; 
     Point currentPoint; 
     bool isInDrag = false; 

     private void root_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
     { 
      var element = sender as FrameworkElement; 
      anchorPoint = e.GetPosition(null); 
      element.CaptureMouse(); 
      isInDrag = true; 
      e.Handled = true; 
     } 

     private void root_MouseMove(object sender, MouseEventArgs e) 
     { 
      if (isInDrag) 
      { 
       var element = sender as FrameworkElement; 
       currentPoint = e.GetPosition(null); 

       var transform = new TranslateTransform 
            { 
             X = (currentPoint.X - anchorPoint.X), 
             Y = (currentPoint.Y - anchorPoint.Y) 
            }; 
       this.RenderTransform = transform; 
       anchorPoint = currentPoint; 
      } 
     } 

     private void root_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
     { 
      if (isInDrag) 
      { 
       var element = sender as FrameworkElement; 
       element.ReleaseMouseCapture(); 
       isInDrag = false; 
       e.Handled = true; 
      } 
     } 

如果改变代码

X = (currentPoint.X - anchorPoint.X), 
Y = (currentPoint.Y - anchorPoint.Y) 

X = (currentPoint.X), 
Y = (currentPoint.Y) 

我可以移动用户控件,但鼠标和用户控件不匹配

+5

@mazbsky - 没有问题,可能也许可能意味着问题的最后几句话是不正确的gramatically。 – 2011-06-08 19:45:44

回答

13

早上好。我睡觉,能想到的)))

private TranslateTransform transform = new TranslateTransform(); 
     private void root_MouseMove(object sender, MouseEventArgs e) 
     { 
      if (isInDrag) 
      { 
       var element = sender as FrameworkElement; 
       currentPoint = e.GetPosition(null); 

       transform.X += currentPoint.X - anchorPoint.X; 
       transform.Y += (currentPoint.Y - anchorPoint.Y); 
       this.RenderTransform = transform; 
       anchorPoint = currentPoint; 
      } 
     } 
+1

不错,但这种方法效率不高。拖动包含大约10个自定义模板控件的网格时,我的CPU负载高达23%! (酷睿i7 3770)没有更好的方法来做到这一点?我还将父容器更改为画布并使用Canvas.SetLeft,但没有性能变化。 – SepehrM 2014-01-05 07:42:56

+0

我建议在鼠标移动时也使用rx节流来处理较少的支持者 – 2015-12-03 11:53:50

+2

如何防止控制超出界限?我开始使用它来拖动控件并且效果很好,但是当用户到达边缘时,它会让控件离开窗口并变得不可见。 – 2016-11-03 16:24:30

6

我真的不确定你想要在你的问题中完成什么,但拇指更容易拖动动作。你可以看到一个解释和示例代码(在底部)here

-2

@Mediator答案基于信息。我已经提出并编辑,以防止控制超出界限。

private TranslateTransform transform = new TranslateTransform(); 
    private void root_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (isInDrag) 
     { 
      var element = sender as FrameworkElement; 
      currentPoint = e.GetPosition(null); 

      transform.X += currentPoint.X - anchorPoint.X; 
      transform.Y += (currentPoint.Y - anchorPoint.Y); 
      if (currentPoint.X < Application.Current.MainWindow.RenderSize.Width && currentPoint.Y < Application.Current.MainWindow.RenderSize.Height 
       && currentPoint.X > 0 && currentPoint.Y > 0) 
      { 
       this.RenderTransform = transform; 
       anchorPoint = currentPoint; 
      } 
      else 
      { 
       transform = new TranslateTransform(); 
       this.RenderTransform = transform; 
      } 
     } 
    } 

但是绑定错误是他们在VS中的输出窗口。

看起来这是WPF中的一个问题,但是微软无法解决这个问题。

欲了解更多资讯:

https://connect.microsoft.com/VisualStudio/feedback/details/1423399/system-windows-data-error-4-when-using-relativesource-findancestor-inside-a-translatetransform-inside-a-style

+0

这会导致轻松避免的“跳跃”行为。 (例如,可以通过引用'Thumb'来避免。)另外,所谓的“错误”与手边的问题完全无关。 – Informagic 2017-10-02 13:28:37