如何在画布内拖动用户控件 [英] How to drag a UserControl inside a Canvas

查看:16
本文介绍了如何在画布内拖动用户控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Canvas,用户可以在其中添加包含表单的 UserControl 子类.用户应该能够在画布周围拖动这些 UserControl.

I have a Canvas in which user can add UserControl subclasses containing a form. User should be able to drag these UserControl around the Canvas.

使用 WPF 执行此操作的最佳做​​法是什么?

What's the best practice to do this with WPF?

推荐答案

这是在 Silverlight 中完成的,而不是在 WPF 中完成,但它应该工作相同.

This is done in silverlight and not in WPF, but it should work the same.

在控件上创建两个私有属性:

Create two private properties on the control:

protected bool isDragging;  
private Point clickPosition;

然后在控件的构造函数中附加一些事件处理程序:

Then attatch some event handlers in the constructor of the control:

this.MouseLeftButtonDown += new MouseButtonEventHandler(Control_MouseLeftButtonDown);
this.MouseLeftButtonUp += new MouseButtonEventHandler(Control_MouseLeftButtonUp);
this.MouseMove += new MouseEventHandler(Control_MouseMove);

现在创建这些方法:

private void Control_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    isDragging = true;
    var draggableControl = sender as UserControl;
    clickPosition = e.GetPosition(this);
    draggableControl.CaptureMouse();
}

private void Control_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    isDragging = false;
    var draggable = sender as UserControl;
    draggable.ReleaseMouseCapture();
}

private void Control_MouseMove(object sender, MouseEventArgs e)
{
    var draggableControl = sender as UserControl;

    if (isDragging && draggableControl != null)
    {
        Point currentPosition = e.GetPosition(this.Parent as UIElement);

        var transform = draggableControl.RenderTransform as TranslateTransform;
        if (transform == null)
        {
            transform = new TranslateTransform();
            draggableControl.RenderTransform = transform;
        }

        transform.X = currentPosition.X - clickPosition.X;
        transform.Y = currentPosition.Y - clickPosition.Y;
    }
}

这里有几点需要注意:
1. 这不必在画布中.它可以在堆栈面板或网格中.
2. 这使得整个控件可拖动,这意味着如果您单击控件中的任意位置并拖动它,则会拖动整个控件.不确定这是否正是您想要的.

A few things to note here:
1. This does not have to be in a canvas. It can be in a stackpanel, or grid as well.
2. This makes the entire control draggable, that means if you click anywhere in the control and drag it will drag the whole control. Not sure if thats exactly what you want.

编辑-
扩展您问题中的一些细节:我实现这一点的最佳方法是创建一个继承自 UserControl 的类,可能称为 DraggableControl 并使用此代码构建,然后所有可拖动控件都应扩展 DraggableControl.

Edit-
Expanding on some of the specifics in your question: The best way that I would implement this is to create a class that inherits from UserControl, maybe called DraggableControl that is built with this code, then all draggable controls should extend the DraggableControl.

编辑 2 - 当您在此控件中有数据网格时会出现一个小问题.如果您对数据网格中的列进行排序,则永远不会触发 MouseLeftButtonUp 事件.我已经更新了代码,以便保护 isDragging.我发现最好的解决方案是将此匿名方法与数据网格的 LostMouseCapture 事件联系起来:

Edit 2 - There is small issue when you have a datagrid in this control. If you sort a column in the datagrid the MouseLeftButtonUp event never fires. I have updated the code so that isDragging is protected. I found the best solution is to tie this anonymous method to the LostMouseCapture event of the datagrid:

this.MyDataGrid.LostMouseCapture += (sender, e) => { this.isDragging = false; };

这篇关于如何在画布内拖动用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆