简体   繁体   English

删除TableLayoutPanel中的特定行

[英]Removing a specific Row in TableLayoutPanel

I have TableLayoutPanel that I programatically add Rows to. 我有TableLayoutPanel,我以编程方式添加Rows。 The User basically choses a Property and that is then displayed in the table along with some controls. 用户基本上选择了一个属性,然后将其与一些控件一起显示在表中。 I think I have a general understanding problem here and I will try to explain it. 我想我在这里有一个普遍的理解问题,我会尝试解释它。

One of the Controls in every row is a 'delete'-Button. 每行中的一个控件是“删除”按钮。 That button should delete the row it is in. What I did is add an eventhandler to the button and set the current rowcount. 该按钮应该删除它所在的行。我所做的是向按钮添加一个事件处理程序并设置当前的rowcount。

deleteTalent.Click += (sender, e) => buttonClickHandler(numberOfRows);

Code of the handler: 处理程序代码:

private void buttonClickHandler(int rowCount)
{
    int count = rowCount - 1;
    for (int i = count; i < (count + 5); i++)
    {
        balanceTable.Controls.RemoveAt(count);
    }
    balanceTable.RowStyles.RemoveAt(count);
    balanceTable.RowCount--;

}

I looked at it for hours and played around. 我看了好几个小时,玩了一下。 But I can't find a working clean solution. 但我找不到一个干净利落的解决方案。 I'm also pretty new to C# 我也是C#的新手

Here's the complete Function that creates a new row: 这是创建新行的完整函数:

private void addBalanceItems(ToolStripMenuItem item)
{
    int numberOfRows = balanceTable.RowCount;
    if (numberOfRows > 1)
    {
        balanceTable.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.AutoSize));

    }
    balanceTable.Height = numberOfRows * 45;
    Steigerungsrechner rechner = new Steigerungsrechner();
    string tag = item.Tag.ToString();

    //change that asap :(
    if (tag == "A") { rechner.column = 1; }
    if (tag == "B") { rechner.column = 2; }
    if (tag == "C") { rechner.column = 3; }
    if (tag == "D") { rechner.column = 4; }
    if (tag == "E") { rechner.column = 5; }
    if (tag == "F") { rechner.column = 6; }
    if (tag == "G") { rechner.column = 7; }
    if (tag == "H") { rechner.column = 8; }

    Label talentName = new Label();
    talentName.Text = item.Text;
    talentName.Height = standardHeight;
    talentName.TextAlign = ContentAlignment.MiddleLeft;
    talentName.AutoSize = true;
    Label cost = new Label();
    cost.TextChanged += (sender, e) => costChangeHandler(cost);
    cost.Height = standardHeight;
    cost.TextAlign = ContentAlignment.MiddleLeft;
    TextBox startValue = new TextBox();
    startValue.TextChanged += (sender, e) => startValueChangeHandler(rechner, startValue, cost);
    startValue.Height = standardHeight;
    startValue.TextAlign = HorizontalAlignment.Center;
    TextBox endValue = new TextBox();
    endValue.TextChanged += (sender, e) => endValueChangeHandler(rechner, endValue, cost);
    endValue.Height = standardHeight;
    endValue.TextAlign = HorizontalAlignment.Center;
    Button deleteTalent = new Button();
    deleteTalent.Text = "x";
    deleteTalent.Click += (sender, e) => buttonClickHandler(numberOfRows);
    deleteTalent.Height = standardHeight;

    balanceTable.Controls.Add(talentName);
    balanceTable.Controls.Add(startValue);
    balanceTable.Controls.Add(endValue);
    balanceTable.Controls.Add(cost);
    balanceTable.Controls.Add(deleteTalent);
    balanceTable.Visible = true;
    balanceTable.RowCount++;
}

Any help would be greatly appreciated! 任何帮助将不胜感激! :) :)

Yeah, removing an arbitrary row from a TableLayoutPanel is not at all intuitive. 是的,从TableLayoutPanel中删除任意行并不是很直观。 They really screwed up the design on this one. 他们真的搞砸了这个设计。

The only way to remove rows is by setting the RowCount property. 删除行的唯一方法是设置RowCount属性。 This alone is strange enough; 仅这一点就足够奇怪了; that property sure seems like it should be read-only and code that does this looks wrong to me every time I see it. 这个属性确实看起来应该是只读的,每次看到它时,这样做的代码对我来说都是错误的。

But beyond that, the consequence of this design is that you cannot remove rows from the middle. 但除此之外,这种设计的结果是你不能从中间删除行。 Resetting the RowCount property will just cause rows to be lopped off of the bottom. 重置RowCount属性只会导致行从底部丢失。

The workaround is a bit unwieldy, with multiple steps to get wrong: 解决方法有点笨拙,有多个步骤出错:

  1. Remove the controls from the row you want to delete 从要删除的行中删除控件
  2. If applicable, move those controls to to another row. 如果适用,请将这些控件移动到另一行。
  3. Move all of the controls in the other rows that come after the row you wish to delete up a row. 移动要删除的行之后的其他行中的所有控件。
  4. Finally, remove the last row by decrementing the value of the RowCount property. 最后,通过递减RowCount属性的值来删除最后一行。

A quick Google search reveals that someone has written and shared code purporting to do this. 一个快速的谷歌搜索显示有人写了和共享代码声称这样做。 It's in VB.NET, but that should be easily translated into your native dialect. 它在VB.NET中,但应该很容易翻译成你的本地方言。

I'll admit that I've been known to just punt and set the RowHeight of the row I wish to "remove" to 0. This way, autosizing does the work for you. 我承认我已经知道只是RowHeight并且将我希望“删除”的行的RowHeight设置为0.这样,自动调整功能可以为您完成工作。 You probably still want to remove the controls it contains, though. 但是,您可能仍希望删除它包含的控件。

Here is a static class that can help you remove any row by it's index: 这是一个静态类,可以帮助您通过它的索引删除任何行:

using System.Windows.Forms;

public static class TableLayoutHelper
{
    public static void RemoveArbitraryRow(TableLayoutPanel panel, int rowIndex)
    {
        if (rowIndex >= panel.RowCount)
        {
            return;
        }

        // delete all controls of row that we want to delete
        for (int i = 0; i < panel.ColumnCount; i++)
        {
            var control = panel.GetControlFromPosition(i, rowIndex);
            panel.Controls.Remove(control);
        }

        // move up row controls that comes after row we want to remove
        for (int i = rowIndex + 1; i < panel.RowCount; i++)
        {
            for (int j = 0; j < panel.ColumnCount; j++)
            {
                var control = panel.GetControlFromPosition(j, i);
                if (control != null)
                {
                    panel.SetRow(control, i - 1);
                }
            }
        }

        var removeStyle = panel.RowCount - 1;

        if (panel.RowStyles.Count > removeStyle)
            panel.RowStyles.RemoveAt(removeStyle);

        panel.RowCount--;
    }
}

One thing to mention: controls that we get via panel.GetControlFromPosition(...) must be visible or it will return null instead of invisible controls. 有一点需要提及:我们通过panel.GetControlFromPosition(...)得到的控件必须是可见的,否则它将返回null而不是不可见的控件。

Removing complete Table - 删除完整的表格 -

tableLayoutPanel1.Controls.Clear();
tableLayoutPanel1.RowStyles.Clear();

Set your Headline of the Table again - 再次 设置你的标题 -

            tableLayoutPanel.RowCount = 1;
            tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
            tableLayoutPanel.Controls.Add(new Label() { Text = "MONTH", Font = new Font("Century Gothic", 12, FontStyle.Bold), ForeColor = Color.LightGray }, 0, tableLayoutPanel.RowCount - 1);
            tableLayoutPanel.Controls.Add(new Label() { Text = "YEAR", Font = new Font("Century Gothic", 12, FontStyle.Bold), ForeColor = Color.LightGray }, 1, tableLayoutPanel.RowCount - 1);
            tableLayoutPanel.Controls.Add(new Label() { Text = "MEASURED WAFERS", Font = new Font("Century Gothic", 12, FontStyle.Bold), ForeColor = Color.LightGray }, 2, tableLayoutPanel.RowCount - 1);

3 Columns - 1 Row 3列 - 1行

Maybe someone can use my codesnipped, works proper good... 也许有人可以使用我的代码,工作正常...

Remove existing controls of rowCount at first 首先删除rowCount现有控件

for(int i = 0; i < panel.ColumnCount; i++){
     Control Control = panel.GetControlFromPosition(i, rowCount);
     panel.Controls.Remove(Control);
  }

Then remove row 然后删除行

panel.RowStyles.RemoveAt(rowCount-1);

You cannot completely delete a row on tablelayoutpanel but there is a workaround: 您无法完全删除tablelayoutpanel上的行,但有一种解决方法:

  1. Remove all the controls in the row, easier if you know the names of the controls cause you can call the dispose method. 如果您知道控件的名称,则可以更轻松地删除行中的所有控件,因为您可以调用dispose方法。
  2. Set the height of the row to maybe 2px using the row style method (eg tablelayoutpanel1.Rowstyle(index).height=2 ) 使用行样式方法将行的高度设置为2px (例如tablelayoutpanel1.Rowstyle(index).height=2

For me this worked wonders the, row was completely collapsed the row regardless of the row index. 对我来说,这工作奇迹,行无论行索引如何都完全折叠了行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM