amdmcm amdmcm - 4 months ago 19
C# Question

How to programmatically remove Form controls

I'm trying to make a winForms application, where, each increase on the numericUpDown should, in the end, make the panel control visible, and create a textbox control, a picturebox, a numericUpDown control and three labels. And each decrease, should remove this group of controls. I've managed to write the code that creates the controls, but I have no idea how to remove them. My only guess, is to assign a name to every control, and then use the

colorPanel.Controls.RemoveByKey()
. Not quite sure what to do with
nameTextBoxPositionY
and
newLabelPositionY
, in their current state, they will probably screw everything up. Or should I just give up, and use a
switch(regionNumber)
, manually create the controls, and just make them visible depending on the numericUpDown value? Which would be quite a chore, considering that the max value for the numericUpDown is 10.

private Label newLabel;
private TextBox nameTextBox;
private NumericUpDown heightNumericUpDown;
private PictureBox colorPictureBox;
private string[] newLabelText = {"Name", "Height", "Color"};

private int newLabelPositionX = -3;
private int newLabelPositionY = 5;

private int nameTextBoxPositionX = 74;
private int nameTextBoxPositionY = 2;
private void numberOfRegions_ValueChanged(object sender, EventArgs e)
{
int regionNumber = Convert.ToInt32(numberOfRegions.Value);
int numberOfLabels = 3;

if (regionNumber > 0)
{
colorPanel.Visible = true;
for (int i = 0; i < regionNumber; i++)
{
nameTextBox = new TextBox();
nameTextBox.Size = new System.Drawing.Size(81, 20);
nameTextBox.Location = new System.Drawing.Point(nameTextBoxPositionX, nameTextBoxPositionY);
colorPanel.Controls.Add(nameTextBox);
nameTextBoxPositionY += 78;
for (int a = 0; a < numberOfLabels; a++)
{
newLabel = new Label();
newLabel.Location = new System.Drawing.Point(newLabelPositionX, newLabelPositionY);
newLabel.Text = newLabelText[a];
colorPanel.Controls.Add(newLabel);
newLabelPositionY += 26;
}
}
newLabelPositionY = 5;
nameTextBoxPositionY = 2;
}
else
{
colorPanel.Visible = false;
}
}

Answer

Thanks for the answers, but I've fiddled with Controls.RemoveByKey() and found the solution:

struct DynamicFormControls
{
    public TextBox textBox;
    public Label label;
}

DynamicFormControls dynamicControls = new DynamicFormControls();
Stack<Control> controlStack = new Stack<Control>();
private string[] newLabelText = {"Name", "Height", "Color"};
private int newLabelPositionX = -3;
private int newLabelPositionY = 5;
private int nameTextBoxPositionX = 74;
private int nameTextBoxPositionY = 2;
private int numberOfLabels = 3;
private int currentValue = 0;
private int previousValue = 0;
private int difference = 0;
private int nameSuffix1 = 1;
private int nameSuffix2 = 1;

private void numberOfRegions_ValueChanged(object sender, EventArgs e)
{
    currentValue = Convert.ToInt32(numberOfRegions.Value);
    if (currentValue == 0)
    {
        colorPanel.Visible = false;
        colorPanel.Size = new System.Drawing.Size(161, 10);
    }
    if (!ValueIncreased())
    {
        RemoveControls();
    }
    else
    {
        colorPanel.Visible = true;            
        CreateControls();
    }
}

private bool ValueIncreased()
{
    if (currentValue > previousValue)
    {
        difference = currentValue - previousValue;
        previousValue = currentValue;
        return true;
    }
    else
    {
        difference = previousValue - currentValue;
        previousValue = currentValue;
        return false;
    }
}

private void CreateControls()
{
    for (int i = 0; i < difference; i++)
    {
        dynamicControls.textBox = new TextBox();
        dynamicControls.textBox.Name = "textBox" + nameSuffix1;
        dynamicControls.textBox.Size = new System.Drawing.Size(81, 20);
        dynamicControls.textBox.Location = new System.Drawing.Point(nameTextBoxPositionX, nameTextBoxPositionY);                
        colorPanel.Controls.Add(dynamicControls.textBox);
        controlStack.Push(dynamicControls.textBox);
        nameTextBoxPositionY += 78;
        nameSuffix1++;                
        for (int a = 0; a < numberOfLabels; a++)
        {
            dynamicControls.label = new Label();
            dynamicControls.label.Name = "label" + nameSuffix2;
            dynamicControls.label.Location = new System.Drawing.Point(newLabelPositionX, newLabelPositionY);
            dynamicControls.label.Text = newLabelText[a];
            colorPanel.Controls.Add(dynamicControls.label);
            controlStack.Push(dynamicControls.label);
            newLabelPositionY += 26;
            nameSuffix2++;
        }
    }
}

private void RemoveControls()
{
    for (int d = 0; d < difference; d++)
    {                
        for (int b = 0; b < 6; b++)
        {
            controlStack.Pop().Dispose();
        }
        nameSuffix1--;            
        if (nameTextBoxPositionY > 2)
        {
            nameTextBoxPositionY -= 78;
        }
        for (int t = 0; t < numberOfLabels; t++)
        {
            nameSuffix2--;
            if (newLabelPositionY > 5)
            {
                newLabelPositionY -= 26;
            }
        }
    }
}