1

我有一个tableLayoutPanel16 个单元格。15 个细胞具有对照。我希望能够在运行时将控件从一个单元格移动到另一个单元格。

我用过

    private void button15_Click(object sender, EventArgs e)
    {
        tableLayoutPanel1.Controls.Remove(button15);

        tableLayoutPanel1.Controls.Add(button15, 3, 3);
    }

这很好用,但我想知道是否有更好的方法来做到这一点???

4

2 回答 2

3

Winforms中,您只能在其父级内移动控件(当然,某些实际上没有父级的控件也有一些例外)。所以这里的想法是,如果你想移动你的一个控件TableLayoutPanel,你必须在按住鼠标时将它的 Parent 设置为你Form的另一个container,当移动时,控件的位置在新的父级中,释放鼠标后,我们必须将控件的Parent设置在TableLayoutPanel后面,当然我们必须找到下拉单元格位置并使用SetCellPosition方法将控件定位在 上TableLayoutPanel,这是给你的演示代码(效果很好),我使用2Button在此演示中,您可以将它们替换为您想要的任何控件:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        //This will prevent flicker
        typeof(TableLayoutPanel).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(tableLayoutPanel1, true, null);
    }
    Point downPoint;
    bool moved;
    //This is used to store the CellBounds together with the Cell position
    //so that we can find the Cell position later (after releasing mouse).
    Dictionary<TableLayoutPanelCellPosition, Rectangle> dict = new Dictionary<TableLayoutPanelCellPosition, Rectangle>();
    //MouseDown event handler for all your controls (on the tableLayoutPanel1)
    private void Buttons_MouseDown(object sender, MouseEventArgs e) {
        Control button = sender as Control;
        button.Parent = this;            
        button.BringToFront();            
        downPoint = e.Location;            
    }
    //MouseMove event handler for all your controls (on the tableLayoutPanel1)
    private void Buttons_MouseMove(object sender, MouseEventArgs e) {
        Control button = sender as Control;
        if (e.Button == MouseButtons.Left) {
            button.Left += e.X - downPoint.X;
            button.Top += e.Y - downPoint.Y;
            moved = true;
            tableLayoutPanel1.Invalidate();
        }
    }
    //MouseUp event handler for all your controls (on the tableLayoutPanel1)
    private void Buttons_MouseUp(object sender, MouseEventArgs e) {
        Control button = sender as Control;
        if (moved) {
            SetControl(button, e.Location);
            button.Parent = tableLayoutPanel1;
            moved = false;
        }
    }
    //This is used to set the control on the tableLayoutPanel after releasing mouse
    private void SetControl(Control c, Point position) {
        Point localPoint = tableLayoutPanel1.PointToClient(c.PointToScreen(position));
        var keyValue = dict.FirstOrDefault(e => e.Value.Contains(localPoint));
        if (!keyValue.Equals(default(KeyValuePair<TableLayoutPanelCellPosition, Rectangle>))) {
            tableLayoutPanel1.SetCellPosition(c, keyValue.Key);
        }
    }
    //CellPaint event handler for your tableLayoutPanel1
    private void tableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e) {
        dict[new TableLayoutPanelCellPosition(e.Column, e.Row)] = e.CellBounds;
        if (moved) {
            if (e.CellBounds.Contains(tableLayoutPanel1.PointToClient(MousePosition))) {
                e.Graphics.FillRectangle(Brushes.Yellow, e.CellBounds);
            }
        }
    }
}

在此处输入图像描述

于 2013-09-08T08:04:25.913 回答
-1

删除锁定并将停靠设置为无并移动!

于 2020-08-21T02:44:41.953 回答