c# - 将文本框添加到 tablelayoutpanel 会导致文本框出现在 'random' 位置

标签 c# .net winforms tablelayoutpanel

我有一个简单的 winform 应用程序,它允许用户将控件拖动到 tablelayoutpanel。但经过一些测试并尝试将控件拖动到特定索引行后,我发现它不起作用,即使使用硬编码索引号也是如此。

使用提供的代码示例,我尝试将文本框添加到行索引 2,但是当我将内容从列表框拖动到 tablelayoutpanel 时,它只是将文本框添加到“随机”位置,如下面的屏幕截图所示

enter image description here

我希望现有的文本框向下移动并为正在添加的文本框腾出位置,据我所知:https://social.msdn.microsoft.com/Forums/windows/en-US/e4312cd8-6031-4a5c-92bf-e8adb1941fe5/insert-row-at-particular-position-in-table-layout-panel?forum=winforms .

我做错了什么吗?

设计师代码:

partial class Form1
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.listBox1 = new System.Windows.Forms.ListBox();
        this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
        this.SuspendLayout();
        // 
        // listBox1
        // 
        this.listBox1.FormattingEnabled = true;
        this.listBox1.Location = new System.Drawing.Point(367, 12);
        this.listBox1.Name = "listBox1";
        this.listBox1.Size = new System.Drawing.Size(190, 407);
        this.listBox1.TabIndex = 0;
        this.listBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseDown);
        // 
        // tableLayoutPanel1
        // 
        this.tableLayoutPanel1.ColumnCount = 1;
        this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
        this.tableLayoutPanel1.Location = new System.Drawing.Point(13, 12);
        this.tableLayoutPanel1.Name = "tableLayoutPanel1";
        this.tableLayoutPanel1.RowCount = 1;
        this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
        this.tableLayoutPanel1.Size = new System.Drawing.Size(332, 407);
        this.tableLayoutPanel1.TabIndex = 1;
        this.tableLayoutPanel1.DragDrop += new System.Windows.Forms.DragEventHandler(this.tableLayoutPanel1_DragDrop);
        this.tableLayoutPanel1.DragEnter += new System.Windows.Forms.DragEventHandler(this.tableLayoutPanel1_DragEnter);
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(569, 431);
        this.Controls.Add(this.tableLayoutPanel1);
        this.Controls.Add(this.listBox1);
        this.Name = "Form1";
        this.Text = "Form1";
        this.ResumeLayout(false);

    }

    #endregion

    private System.Windows.Forms.ListBox listBox1;
    private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
}

表单代码:

public partial class Form1 : Form
{
    private int tempInt = 0;

    public Form1()
    {
        InitializeComponent();
        listBox1.Items.AddRange(new object[] { "test" });
        tableLayoutPanel1.AllowDrop = true;
        tableLayoutPanel1.GrowStyle = TableLayoutPanelGrowStyle.AddRows;
        tableLayoutPanel1.AutoScroll = true;
        tableLayoutPanel1.RowCount = 3;
    }

    private void listBox1_MouseDown(object sender, MouseEventArgs e)
    {
        tempInt++;
        DoDragDrop("test" + tempInt, DragDropEffects.Copy);
    }

    private void tableLayoutPanel1_DragEnter(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.Copy;
    }

    private void tableLayoutPanel1_DragDrop(object sender, DragEventArgs e)
    {
        string text = e.Data.GetData(typeof(String)) as string;
        TextBox tb = new TextBox();
        tb.Dock = DockStyle.Fill;
        tb.Text = text;
        // I want to add the textbox to the second row
        tableLayoutPanel1.Controls.Add(tb, 0, 2);
        tableLayoutPanel1.SetRow(tb, 2);
    }
}

编辑:

根据 DonBoitnott 的建议添加代码

    private void tableLayoutPanel1_DragDrop(object sender, DragEventArgs e)
    {
        string text = e.Data.GetData(typeof(String)) as string;
        TextBox tb = new TextBox();
        tb.Dock = DockStyle.Fill;
        tb.Text = text;
        tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
        for (int i = 0; i < tableLayoutPanel1.Controls.Count; i++)
        {
            int pos = tableLayoutPanel1.GetRow(tableLayoutPanel1.Controls[i]);
            if (pos > 1)
            {
                tableLayoutPanel1.SetRow(tableLayoutPanel1.Controls[i], pos + 1);
            }
        }
        tableLayoutPanel1.Controls.Add(tb, 0, 2);
    }

最佳答案

试试这个修改后的表单类,我在整个过程中做了一些更改:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            listBox1.Items.AddRange(new Object[] { "TextBox" });
            tableLayoutPanel1.AllowDrop = true;
            tableLayoutPanel1.GrowStyle = TableLayoutPanelGrowStyle.AddRows;
            tableLayoutPanel1.AutoScroll = true;
            tableLayoutPanel1.RowStyles.Clear();
            tableLayoutPanel1.ColumnStyles.Clear();
            tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f));
        }

        private void listBox1_MouseDown(Object sender, MouseEventArgs e)
        {
            var count = tableLayoutPanel1.Controls.Count;
            DoDragDrop($"test{count + 1}", DragDropEffects.Copy);
        }

        private void tableLayoutPanel1_DragEnter(Object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }

        private void tableLayoutPanel1_DragDrop(Object sender, DragEventArgs e)
        {
            var tb = new TextBox();
            tb.Dock = DockStyle.Fill;
            tb.Text = (e.Data.GetData(typeof(String)) as String);

            var newRow = tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
            var ctrl = tableLayoutPanel1.GetChildAtPoint(tableLayoutPanel1.PointToClient(new Point(e.X, e.Y)));
            if (ctrl != null)
            {
                var pos = tableLayoutPanel1.GetRow(ctrl);
                for (Int32 i = tableLayoutPanel1.RowStyles.Count - 2; i >= pos; i--)
                {
                    var c = tableLayoutPanel1.GetControlFromPosition(0, i);
                    if (c != null)
                        tableLayoutPanel1.SetRow(c, i + 1);
                }
                tableLayoutPanel1.Controls.Add(tb, 0, pos);
            }
            else
                tableLayoutPanel1.Controls.Add(tb, 0, newRow);
        }
    }

基本步骤是:

  1. 我是否拖放到了现有控件上?如果是,请确定位置。
  2. 如果是这样,从下到上工作,将每个控件向下移动一个槽。您必须避免重叠,两个控件不能占据同一个单元格。
  3. 如果是这样,将新控件插入到放置点处新空出的插槽中。
  4. 如果没有,只需在末尾添加控件即可。

关于c# - 将文本框添加到 tablelayoutpanel 会导致文本框出现在 'random' 位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42074037/

相关文章:

C# 使用反射访问窗口属性

c# - 应用程序在 Galaxy S3 Mini 中崩溃,但在其他型号中有效

.net - C# 中的 Java RuntimeException 等价物?

C#:表单和 if 语句

c# - 报表查看器 - 请求 SqlClientPermission 类型的权限失败

c# - 通用类型指针?并将字节数组转换为给定类型的泛型?

c# - .net core 5 中具有参数依赖关系的全局过滤器

c# - 如何编写要在程序集中的任何方法之前执行的代码?

c# - 引用类型的堆内存引用存储在哪里?

c# - 根据文本确定自定义消息框的窗口大小