拖放按钮(按钮不会跟随)

时间:2016-03-12 20:22:20

标签: c# winforms drag-and-drop

我在面板和面板中拖放按钮以识别它并显示带按钮名称的消息时遇到了一些麻烦

到目前为止,我处理了拖放和识别的部分,但是我忽略了拖动的视觉风格,当我用鼠标按下它只会坐在同一个地方时,它不会跟随光标。如何使它跟随鼠标?

    public Form1()
    {
        InitializeComponent();

        panel1.AllowDrop = true;
        panel1.DragEnter += panel_DragEnter;
        panel1.DragDrop += panel_DragDrop;
        button1.MouseDown += button1_MouseDown;
    }

    private void button1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        button1.DoDragDrop(button1.Text, DragDropEffects.Copy | DragDropEffects.Move);
        button1.Location= new Point(e.X, e.Y);
    }

    private void panel_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
    {
        e.Effect = DragDropEffects.Move;
        if (e.Data.GetDataPresent(DataFormats.Text))
            e.Effect = DragDropEffects.Copy;
        else
            e.Effect = DragDropEffects.None;
    }

    private void panel_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
    {
        MessageBox.Show(e.Data.GetData(DataFormats.Text).ToString());

    }

1 个答案:

答案 0 :(得分:0)

您必须记住,DoDragDrop方法不会返回您放置对象的位置。 DragDrop事件处理该事件。

要在拖动时移动控件,请使用面板的DragOver事件。在实现中,您需要补偿EventArgs中的X和Y坐标是基于屏幕的这一事实,而您需要基于Client的坐标来正确定位控件。 PointToClient有助于:

private void panel_DragOver(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(typeof(Button).FullName))
    {
        var draggedButton = (Button)e.Data.GetData(typeof(Button).FullName);

        var screenpos = new Point(e.X, e.Y);
        var clientPos =  panel1.PointToClient(screenpos);
        // calc offset
        draggedButton.Location = new Point(
            clientPos.X + panel1.Left,
            clientPos.Y + panel1.Top);
    }
}

请注意,您的数据现在包含实际的Button,而不仅仅包含文本。这使您可以拖动多个按钮,而不仅仅是button1。

您的DragDrop事件现在应如下所示:

private void panel_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
    if (e.Data.GetDataPresent(typeof(Button).FullName))
    {
        var draggedButton = (Button)e.Data.GetData(typeof(Button).FullName);
        MessageBox.Show(draggedButton.Text);

        var screenpos = new Point(e.X, e.Y);
        var clientPos = panel1.PointToClient(screenpos);
        draggedButton.Location = new Point(
            clientPos.X + panel1.Left,
            clientPos.Y + panel1.Top);
    }
}

DragEnter只是略有改动,因此它可以处理Button控件而不是文本:

private void panel_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
    e.Effect = DragDropEffects.Move;

    if (e.Data.GetDataPresent(typeof(Button).FullName)) // button
        e.Effect = DragDropEffects.Copy;
    else
        e.Effect = DragDropEffects.None;
}

最后让它全部启动并连接构造函数代码和按钮的MouseDown实现:

public Form1()
{
    InitializeComponent();
    panel1.AllowDrop = true;
    panel1.DragEnter += panel_DragEnter;
    panel1.DragDrop += panel_DragDrop;
    panel1.DragOver += panel_DragOver;
    button1.MouseDown += button1_MouseDown;

}

private void button1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
    button1.DoDragDrop(button1, DragDropEffects.Copy | DragDropEffects.Move);
}