如何将一个帆布内的用户控件 [英] How to drag a UserControl inside a Canvas

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

问题描述

我在写我的第一个WPF应用程序。我有一个画布中,用户可以添加一个包含用户控件形式的子类。用户应该能够拖动画布这些用户控件。什么是与WPF做到这一点的最佳做法?
谢谢你。

I'm writing my first WPF application. 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. What's the best practice to do this with WPF? Thanks.

推荐答案

这是在Silverlight,而不是在WPF做,但它应该工作。

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


  1. 创建上的控制两个私有属性:

  1. Create two private properties on the control:

保护布尔isDragging;结果
私人点clickPosition;

protected bool isDragging;
private Point clickPosition;

然后attatch一些事件处理的控制的构造函数:

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.本不必在画布。它可以是在一个StackPanel中,或网格为好。结果,
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.

编辑 - 结果
扩大一些在你的问题的细节中:
我会实现这个的最好方法是创建一个从用户控件,这是建立与此code,则所有可拖动控制应延长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 - 有小问题,当你有这个控件的DataGrid。如果排序的事件的MouseLeftButtonUp永远不会触发DataGrid中的一个列。我已经更新了code,使isDragging保护。我找到了最好的解决方案是,以配合该匿名方法到DataGrid的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天全站免登陆