如何允许用户在窗体上移动控件

时间:2010-09-23 18:03:50

标签: c# .net winforms

我有一个winform,我希望允许用户移动一个控件。

控件是(现在)一条垂直线:带边框且宽度为1的标签。

上下文不是很重要,但无论如何我都会给你。我有一些带有图形的背景,我希望用户能够在图形上方滑动指南。图形由NPlots库制作。它看起来像这样: http://www.ibme.de/pictures/xtm-window-graphic-ramp-signals.png

如果我能找到用户如何点击并拖动屏幕周围的标签/线控制,我可以解决我的指南问题。请帮忙。

5 个答案:

答案 0 :(得分:9)

此代码可能会有点复杂,但实质上您需要捕获表单上的MouseDown,MouseMove和MouseUp事件。像这样:

public void Form1_MouseDown(object sender, MouseEventArgs e)
{
    if(e.Button != MouseButton.Left)
        return;

    // Might want to pad these values a bit if the line is only 1px,
    // might be hard for the user to hit directly
    if(e.Y == myControl.Top)
    {
        if(e.X >= myControl.Left && e.X <= myControl.Left + myControl.Width)
        {
            _capturingMoves = true;
            return;
        }
    }

    _capturingMoves = false;
}

public void Form1_MouseMove(object sender, MouseEventArgs e) 
{
    if(!_capturingMoves)
        return;

    // Calculate the delta's and move the line here
}

public void Form1_MouseUp(object sender, MouseEventArgs e) 
{
    if(_capturingMoves)
    {
        _capturingMoves = false;
        // Do any final placement
    }
}

答案 1 :(得分:3)

在WinForms中,您可以处理控件的MouseDown,MouseMove和MouseUp事件。在MouseDown上,设置一些位或引用,告诉您的表单单击鼠标的控件是什么,并从MouseEventArgs中捕获鼠标的X和Y.在MouseMove上,如果设置了控件,则通过上次捕获的X和Y与当前坐标之间的差异来调整其X和Y.在MouseUp上,释放控件。

我会为此设置一个“编辑模式”;当用户进入此模式时,应分离表单控件的当前事件处理程序,并附加移动处理程序。如果您想要保留或恢复这些更改(就像您正在创建一个客户端可以用来自定义窗口布局的自定义表单设计器),您还需要能够获取前后布局的某些快照。控件。

答案 2 :(得分:2)

我写了一个组件来做到这一点:在窗体上移动一个控件(或在屏幕上移动一个无边框的窗体)。您甚至可以从设计人员处使用它,而无需编写任何代码。

http://www.thomaslevesque.com/2009/05/06/windows-forms-automatically-drag-and-drop-controls-dragmove/

答案 3 :(得分:0)

这是一种可用于任何控件的扩展方法。它使用Rx,基于A Brief Introduction to the Reactive Extensions for .NET, Rx帖子和Wes Dyer的样本。

public static class FormExtensions
{
    public static void EnableDragging(this Control c)
    {
        // Long way, but strongly typed.        
        var downs =
            from down in Observable.FromEvent<MouseEventHandler, MouseEventArgs>(
                eh => new MouseEventHandler(eh),
                eh => c.MouseDown += eh,
                eh => c.MouseDown -= eh)
            select new { down.EventArgs.X, down.EventArgs.Y };

        // Short way.        
        var moves = from move in Observable.FromEvent<MouseEventArgs>(c, "MouseMove")
                    select new { move.EventArgs.X, move.EventArgs.Y };

        var ups = Observable.FromEvent<MouseEventArgs>(c, "MouseUp");

        var drags = from down in downs
                    from move in moves.TakeUntil(ups)
                    select new Point { X = move.X - down.X, Y = move.Y - down.Y };

        drags.Subscribe(drag => c.SetBounds(c.Location.X + drag.X, c.Location.Y + drag.Y, 0, 0, BoundsSpecified.Location));
    }
}

用法:

按钮button1 = new Button();

button1.EnableDragging();

答案 4 :(得分:0)

老实说,有一种更简单的方法可以初始化一个名为你喜欢的全局布尔变量,在本例中为isMouseClicked。在您的控制中,您希望允许拖动您的鼠标按下事件,

确保这些事件是您的控件事件,而不是您的表单事件。

if (e.button == MouseButtons.left)
    //this is where you set the boolean to true

然后转到鼠标移动事件

if (isMouseClicked == true)
    //You then set your location of your control. See below:
    Button1.Location = new Point(MousePosition.X, MousePosition.Y);

点击鼠标时,请务必将isMouseClicked设为false;