27

プログラムで行を追加するTableLayoutPanelがあります。ユーザーは基本的にプロパティを選択し、それがいくつかのコントロールとともにテーブルに表示されます。ここで一般的な理解の問題があると思いますので、説明しようと思います。

すべての行のコントロールの1つは、「削除」ボタンです。そのボタンは、それが入っている行を削除するはずです。私がしたことは、ボタンにイベントハンドラーを追加し、現在の行数を設定することです。

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

ハンドラーのコード:

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--;

}

私はそれを何時間も見て遊んだ。しかし、私は実用的なクリーンな解決策を見つけることができません。私もC#にかなり慣れていません

新しい行を作成する完全な関数は次のとおりです。

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++;
}

どんな助けでも大歓迎です!:)

4

5 に答える 5

29

ええ、TableLayoutPanelから任意の行を削除することはまったく直感的ではありません。彼らは本当にこれのデザインを台無しにしました。

行を削除する唯一の方法は、RowCountプロパティを設定することです。これだけでも十分奇妙です。そのプロパティは確かに読み取り専用である必要があるように見え、これを行うコードは私が見るたびに間違っているように見えます。

しかし、それを超えると、この設計の結果、中央から行を削除できなくなります。プロパティをリセットするRowCountと、行が下から削除されます。

回避策は少し扱いに​​くく、間違いを犯すための複数の手順があります。

  1. 削除する行からコントロールを削除します
  2. 該当する場合は、それらのコントロールを別の行に移動します。
  3. 行を削除する行の後にある他の行のすべてのコントロールを移動します。
  4. 最後に、プロパティの値をデクリメントして最後の行を削除しRowCountます。

グーグルですばやく検索すると、誰かがこれを行うことを目的としたコードを作成して共有していることがわかります。これはVB.NETにありますが、ネイティブの方言に簡単に変換できるはずです。

私がRowHeight「削除」したい行のをパントして0に設定することで知られていることを認めます。このように、自動サイズ設定が自動的に機能します。ただし、おそらくそれでも含まれているコントロールを削除する必要があります。

于 2013-03-20T23:08:12.310 に答える
22

これは、インデックスによって行を削除するのに役立つ静的クラスです。

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

言及する1つのこと:私たちが経由するコントロールはpanel.GetControlFromPosition(...)表示されている必要があります。そうでない場合、非表示nullのコントロールの代わりに戻ります。

于 2015-07-12T19:58:25.263 に答える
2

rowCount最初にの既存のコントロールを削除します

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

次に行を削除します

panel.RowStyles.RemoveAt(rowCount-1);
于 2017-03-22T06:41:58.297 に答える
1

完全なテーブルの削除-

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

テーブルの見出しをもう一度設定します-

            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列-1行

たぶん誰かが私のコードニップを使用することができ、適切に機能します...

于 2017-03-31T07:32:23.880 に答える
0

上の行を完全に削除することはできませんtablelayoutpanelが、回避策があります。

  1. 行内のすべてのコントロールを削除します。コントロールの名前がわかっている場合は、disposeメソッドを呼び出すことができます。
  2. 行の高さをおそらく2px行スタイルの方法を使用して設定します(例tablelayoutpanel1.Rowstyle(index).height=2

私にとって、これは不思議に思いました。行のインデックスに関係なく、行は完全に折りたたまれていました。

于 2017-10-14T16:51:08.950 に答える