web-dev-qa-db-fra.com

Suppression d'une ligne spécifique dans TableLayoutPanel

J'ai TableLayoutPanel que j'ajoute par programme à des lignes. En gros, l’utilisateur choisit une propriété qui est ensuite affichée dans la table avec quelques contrôles. Je pense que j'ai un problème de compréhension générale ici et je vais essayer de l'expliquer.

L'un des contrôles de chaque ligne est un bouton 'delete'. Ce bouton devrait supprimer la ligne dans laquelle il se trouve. Ce que j'ai fait est d'ajouter un gestionnaire d'événements au bouton et de définir le nombre de lignes actuel.

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

Code du manutentionnaire:

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

}

Je l'ai regardé pendant des heures et j'ai joué. Mais je ne trouve pas de solution propre qui fonctionne. Je suis aussi assez nouveau en C #

Voici la fonction complète qui crée une nouvelle ligne:

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

Toute aide serait grandement appréciée! :)

19
sebsn

Oui, supprimer une ligne arbitraire d'un TableLayoutPanel n'est pas du tout intuitif. Ils ont vraiment bousillé la conception de celui-ci.

La seule façon de supprimer des lignes consiste à définir la propriété RowCount . Cela seul est assez étrange; il semble que cette propriété devrait être en lecture seule et le code qui le fait ne me semble pas correct chaque fois que je le vois.

Mais au-delà de cela, la conséquence de cette conception est que vous ne pouvez pas supprimer les lignes du milieu. Si vous réinitialisez la propriété RowCount, les lignes seront simplement coupées du bas.

La solution de contournement est un peu lourde, avec plusieurs étapes pour se tromper:

  1. Supprimez les contrôles de la ligne que vous souhaitez supprimer
  2. Le cas échéant, déplacez ces contrôles vers une autre ligne.
  3. Déplacez tous les contrôles dans les autres lignes qui suivent la ligne que vous souhaitez supprimer d'une ligne.
  4. Enfin, supprimez la dernière ligne en décrémentant la valeur de la propriété RowCount.

Une recherche rapide sur Google révèle que quelqu'un a un code écrit/partagé prétendant le faire. C'est en VB.NET, mais cela devrait être facilement traduit dans votre dialecte natif.

J'admets que l'on m'a dit de simplement rajouter de l'argent et de mettre la RowHeight de la ligne que je souhaite "supprimer" à 0. De cette façon, la taille automatique fait le travail pour vous. Cependant, vous souhaiterez probablement toujours supprimer les contrôles qu’il contient.

23
Cody Gray

Le code permettant de supprimer une ligne à une position donnée est donné ci-dessous. Une chose à mentionner: les contrôles que nous obtenons par panel.GetControlFromPosition (...) doit être visible ou sinon, il retournera null au lieu de contrôles invisibles.

    public void remove_row(TableLayoutPanel panel, int row_index_to_remove)
    {
        if (row_index_to_remove >= 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, row_index_to_remove);
            panel.Controls.Remove(control);
        }

        // move up row controls that comes after row we want to remove
        for (int i = row_index_to_remove + 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);
                }
            }
        }

        // remove last row
        panel.RowStyles.RemoveAt(panel.RowCount - 1);
        panel.RowCount--;
    }
11

Enlever compléter le tableau -

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

Set votre Titre de la table encore

            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 colonnes - 1 rangée

Peut-être que quelqu'un peut utiliser mon code, fonctionne correctement ...

0
Ricardo Fercher

Vous ne pouvez pas supprimer complètement une ligne sur tablelayoutpanel, mais il existe une solution de contournement: 

  1. Supprimez tous les contrôles de la ligne, plus facilement si vous connaissez les noms des contrôles car vous pouvez appeler la méthode dispose.
  2. Définissez la hauteur de la ligne sur peut-être 2px à l'aide de la méthode de style de ligne .__ (par exemple tablelayoutpanel1.Rowstyle(index).height=2)

Pour moi, cela a fonctionné à merveille, la ligne a été complètement réduite, quel que soit l'index de la ligne.

0
sailas mwakurudza

Supprimer les contrôles existants de rowCount au début

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

Puis retirez la rangée

panel.RowStyles.RemoveAt(rowCount-1);
0
Shree Krishna