Professor Zoom
Professor Zoom

Reputation: 349

How to delete (remove) space between textboxes after remove some controls?

I'm new working with C# and I'm asking on here because I didn't find a solution searching in google and other questions on SO, I will explain what my example application does:

When I run it it display a form with a textbox by default, this textbox always will be shown, after type some text and press enter it will generate a new textbox and a new button (all the controls even the default textbox are inside a panel), and the new textboxes have the same functionality as the default textbox, when I click on the button generated next to its textbox it removes the button itself and the textbox but after that if I remove some random textboxes it leaves a space between these controls, how can reorganize this content to dont let space between them?

enter image description here

As you can see in the image, can you tell me how can fix this or give me an advice to achieve this? thank you, by the way this is the method I use to generate the buttons and textboxes

private void GenerarTextBox()
{
    panelContenedor.VerticalScroll.Value = panelContenedor.VerticalScroll.Minimum;

    TextBox tb = new TextBox();
    tb.Text = "Prueba " + id;
    tb.Name = "txtBox" + id;
    tb.KeyDown += new KeyEventHandler(TextBox_Keydown);

    Button bt = new Button();
    bt.Cursor = Cursors.Hand;
    bt.Text = "X";
    bt.Name = "btnPrueba" + id;
    bt.Click += new EventHandler(ClickBotones);

    Point p = new Point(20, 30 * id);
    Point pb = new Point(130, 30 * id);

    tb.Location = p;
    bt.Location = pb;

    panelContenedor.Controls.Add(tb);
    panelContenedor.Controls.Add(bt);

    tb.Focus();
    id++;
}

And this to remove the textboxes and the buttons

private void ClickBotones(object sender, EventArgs e)
{
    Button bt = sender as Button;

    string nombreBoton = bt.Name;
    string idBoton = nombreBoton.Substring(9);
    string nombreTextBox = "txtBox" + idBoton;

    foreach (Control item in panelContenedor.Controls.OfType<Control>())
    {
        if (item.Name == nombreTextBox)
        {
            panelContenedor.Controls.Remove(item);
            panelContenedor.Controls.Remove(bt);
        }
    }
}

Upvotes: 2

Views: 257

Answers (2)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112712

You could place your dynamic controls on a FlowLayoutPanel. Either directly or grouped together in a Panel or UserControl.

Set the FlowDirection property of the FlowLayoutPanel to TopDown. The FlowLayoutPanel will then arrange your controls automatically. You can also set the WrapContents property to False and AutoScroll to true to make the scroll bar appear.

Alternatively you can use FlowDirection = LeftToRight, place the text box and the button directly on the FlowLayoutPanel and let the child controls wrap (WrapContents = True). In the child controls, a new property FlowBreak appears. It can be set to True for the last control to appear in a row and let the next one wrap independently of the width of the FlowLayoutPanel.

You can also play with the Margin property of the child controls to control their layout in the FlowLayoutPanel as the Location property becomes useless.

The FlowLayoutPanel (as well as the Panel) is available in the Toolbox in the section "Containers".

Upvotes: 3

Aldert
Aldert

Reputation: 4323

When you delete the controls, you need to do a recalc of the positions. So when you have added them in sequence, you can go with:

bool repos = false;
Point p;
foreach (Control item in panelContenedor.Controls.OfType<Control>())
    {
        if (repos)
        {
             Point tmp = item.Location;              
             item.Location = p;
             p = tmp;
        }


        if (item.Name == nombreTextBox)
        {
            panelContenedor.Controls.Remove(item);
            panelContenedor.Controls.Remove(bt);
            repos = true;
            p = item.Location;
        }

    }

Upvotes: 0

Related Questions