2012-10-31 44 views
2

我在Silverlight 4中对我的RichTextBox有一个拖/放行为,但我遇到了一个小对齐问题。拖放需要数学修补

我希望用户能够“抓住”RichTextBox的任何边界并拖放它。 RichTextBox应该相对于用户“抓住”RichTextBox的位置进行拖动。但相反,只要用户开始拖动,RichTextBox就会“捕捉”到鼠标位置的中间位置,而不是相对于鼠标位置的位置。

所以,如果我抢到右下角,如下面的...

https://skydrive.live.com/redir?resid=DCC93DD825EF3F43!658

它“捕捉”到拖动的起点鼠标中间的位置,如下面...

https://skydrive.live.com/redir?resid=DCC93DD825EF3F43!659

这里是我的拖码。我假设我的数学是错误的(在MouseMove事件中)?


public class CustomRichTextBox : RichTextBox 
{ 
    private bool isDragging = false; 

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) 
    { 
     base.OnMouseLeftButtonDown(e); 

     bool isDragAllowed = false; 
     Point pt = e.GetPosition(this); 

     if (pt.Y >= 0 && pt.Y <= this.BorderThickness.Top) 
      // Allow dragging if the mouse is down on the top border 
      isDragAllowed = true; 
     else if (pt.Y >= (this.RenderSize.Height - this.BorderThickness.Bottom) && pt.Y <= this.RenderSize.Height) 
      // Allow dragging if the mouse is down on the bottom border 
      isDragAllowed = true; 
     else if (pt.X >= 0 && pt.X <= this.BorderThickness.Left) 
      // Allow dragging if the mouse is down on the left border 
      isDragAllowed = true; 
     else if (pt.X >= (this.RenderSize.Width - this.BorderThickness.Right) && pt.X <= this.RenderSize.Width) 
      // Allow dragging if the mouse is down on the right border 
      isDragAllowed = true; 

     if (!isDragAllowed) 
      return; 

     this.CaptureMouse(); 
     isDragging = true; 
    } 

    protected override void OnMouseMove(MouseEventArgs e) 
    { 
     base.OnMouseMove(e); 

     if (isDragging) 
     { 
      CustomRichTextBox elem = this; 
      CompositeTransform ct = (CompositeTransform)elem.RenderTransform; 
      UIElement parent = (UIElement)elem.Parent; 

      ct.TranslateX = e.GetPosition(parent).X - (parent.RenderSize.Width/2); 
      ct.TranslateY = e.GetPosition(parent).Y - (parent.RenderSize.Height/2); 
     } 
    } 

    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) 
    { 
     base.OnMouseLeftButtonUp(e); 

     isDragging = false; 
     this.ReleaseMouseCapture(); 
    } 
} 

回答

1

现在缺少这里是一个参考点到拖动开始的位置。在鼠标移动事件中,您试图将控件转换为鼠标的当前位置,而不是与当前原始位置之间的增量。

或者通过使用相对坐标,您可以将相对于控件的鼠标单击位置存储起来,并简单地将它从OnMove中的当前位置中减去。这是在下面的示例中发生的情况。

请注意,这是没有CompositeTransform的WPF。 从其减去母公司的RenderSize看起来像一个错误给我,也可能是在WPF和Silverlight的差别,反正我希望这有助于解决它:

public class CustomRichTextBox : RichTextBox 
{ 
    private bool isDragging = false; 
    private Point draggingPoint; 

    protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) 
    { 
     base.OnPreviewMouseLeftButtonDown(e); 

     bool isDragAllowed = false; 
     Point pt = e.GetPosition(this); 

     if (pt.Y >= 0 && pt.Y <= this.BorderThickness.Top) 
      // Allow dragging if the mouse is down on the top border 
      isDragAllowed = true; 
     else if (pt.Y >= (this.RenderSize.Height - this.BorderThickness.Bottom) && pt.Y <= this.RenderSize.Height) 
      // Allow dragging if the mouse is down on the bottom border 
      isDragAllowed = true; 
     else if (pt.X >= 0 && pt.X <= this.BorderThickness.Left) 
      // Allow dragging if the mouse is down on the left border 
      isDragAllowed = true; 
     else if (pt.X >= (this.RenderSize.Width - this.BorderThickness.Right) && pt.X <= this.RenderSize.Width) 
      // Allow dragging if the mouse is down on the right border 
      isDragAllowed = true; 

     if (!isDragAllowed) 
      return; 

     draggingPoint = pt; 

     this.CaptureMouse(); 
     isDragging = true; 
    } 

    protected override void OnPreviewMouseMove(MouseEventArgs e) 
    { 
     base.OnPreviewMouseMove(e); 

     if (isDragging) 
     { 
      CustomRichTextBox elem = this; 
      TransformGroup ct = new TransformGroup(); 
      UIElement parent = (UIElement)elem.Parent; 

      TranslateTransform tr = new TranslateTransform(
       e.GetPosition(parent).X - elem.RenderSize.Width + this.BorderThickness.Left - draggingPoint.X, 
       e.GetPosition(parent).Y - elem.RenderSize.Height + this.BorderThickness.Top - draggingPoint.Y); 

      ct.Children.Add(tr); 

      elem.RenderTransform = ct; 
     } 
    } 

    protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e) 
    { 
     base.OnPreviewMouseLeftButtonUp(e); 

     isDragging = false; 
     this.ReleaseMouseCapture(); 
    } 
} 
+0

非常感谢!这很有道理。我会继续进行必要的修改:) – Maximus