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



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

到目前为止,我

管理了拖放和识别的部分,但是我错过了拖动的视觉风格,当我用鼠标按下时,它只会坐在同一个地方,它不会跟随光标。如何让它跟随鼠标?

    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());
    }

您必须记住,DoDragDrop 方法不会返回您放置对象的 Position。DragDrop事件处理这个问题。

若要在拖动时移动控件,请使用面板的 DragOver 事件。在实现中,您需要补偿以下事实:EventArgs 中的 X 和 Y 坐标是基于屏幕的,而您需要基于客户端的坐标来正确定位控件。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);
    }
}

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

您的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);
}

最新更新