我在 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();
}
}
最佳答案
这里缺少的是拖动开始位置的引用点。在鼠标移动事件中,您试图将控件转换为鼠标的当前位置,而不是当前 和原始 位置之间的增量。
或者通过使用相对坐标,您可以存储鼠标点击相对于控件的位置,并简单地从 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();
}
}
关于c# - 拖放需要数学修复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13160125/