28 votes

Suppression d'une ligne spécifique dans TableLayoutPanel

J'ai un TableLayoutPanel auquel j'ajoute des rangées par programme. L'utilisateur choisit une propriété qui est ensuite affichée dans le tableau avec quelques contrôles. Je pense que j'ai un problème de compréhension générale et je vais essayer de l'expliquer.

L'un des contrôles de chaque ligne est un bouton "supprimer". Ce bouton doit supprimer la ligne dans laquelle il se trouve. Ce que j'ai fait, c'est ajouter un eventhandler au bouton et définir le rowcount actuel.

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

Code du gestionnaire :

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é avec. Mais je n'arrive pas à trouver une solution propre et efficace. Je suis également assez novice 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 ! :)

29voto

Cody Gray Points 102261

Oui, supprimer une ligne arbitraire d'un TableLayoutPanel, c'est pas du tout intuitif. Ils se sont vraiment trompés dans la conception de ce produit.

La seule façon de supprimer des lignes est de définir le paramètre RowCount propriété. Ce seul fait est déjà assez étrange ; cette propriété semble vraiment devoir être en lecture seule et le code qui fait cela me semble erroné à chaque fois que je le vois.

Mais au-delà de cela, la conséquence de cette conception est qu'il n'est pas possible de retirer des lignes du milieu. La réinitialisation de la RowCount aura pour effet de couper les rangées du bas.

La solution de contournement est un peu difficile à mettre en œuvre, avec de nombreuses étapes à franchir 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 sur une autre ligne.
  3. Déplacez vers le haut toutes les commandes des autres lignes qui viennent après la ligne que vous souhaitez supprimer.
  4. Enfin, on supprime la dernière ligne en décrémentant la valeur de l'élément RowCount propriété.

Une recherche rapide sur Google révèle que quelqu'un a code écrit et partagé qui prétendent le faire. Il est en VB.NET, mais cela devrait être le cas. facile à traduire dans votre langue maternelle.

J'admets qu'il m'est arrivé de me contenter d'un simple coup de patte et de mettre en place le RowHeight de la ligne que je souhaite "supprimer" à 0. De cette façon, le dimensionnement automatique fait le travail à votre place. Cependant, vous voudrez probablement toujours supprimer les contrôles qu'elle contient.

24voto

Voici une classe statique qui peut vous aider à supprimer n'importe quelle ligne en fonction de son 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--;
    }
}

Une chose à mentionner : les contrôles que nous obtenons par l'intermédiaire de panel.GetControlFromPosition(...) doit être visible, sinon il renverra null au lieu de contrôles invisibles.

2voto

Shree Krishna Points 2556

Supprimer les contrôles existants de rowCount dans un premier temps

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

Ensuite, supprimer la ligne

panel.RowStyles.RemoveAt(rowCount-1);

1voto

Ricardo Fercher Points 187

Suppression Tableau complet -

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

Set (jeu de mots) votre À la une du tableau à nouveau -

            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 ligne

Peut-être que quelqu'un pourrait utiliser mes codesnippés, qui fonctionnent bien...

0voto

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

  1. Supprimer tous les contrôles de la ligne, plus facile si vous connaissez les noms des contrôles car vous pouvez appeler la méthode dispose.
  2. Fixer la hauteur de la ligne à peut-être 2px en utilisant la méthode du style de ligne (par ex. tablelayoutpanel1.Rowstyle(index).height=2 )

Pour moi, cela a fonctionné à merveille : la ligne était complètement effondrée, quel que soit l'index de la ligne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X