【问题标题】:Drag & Drop needs a math fix拖放需要数学修复
【发布时间】:2012-10-31 14:22:52
【问题描述】:

我的 RichTextBox 在 Silverlight 4 中有拖放行为,但我遇到了一个小问题。

我希望用户能够“抓取” 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();
    }
}

【问题讨论】:

    标签: c# silverlight


    【解决方案1】:

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

    或者通过使用相对坐标,您可以存储鼠标单击相对于控件的位置,然后在 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();
        }
    }
    

    【讨论】:

    • 非常感谢!这很有意义。我将继续进行必要的更改:)
    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多