简体   繁体   中英

C# winforms dynamically created button controls

I have an add user button which dynamically adds a remove button and a username textbox when the user clicks it. The user can click the button as many times as they like and the controls will continue to add.

I am having trouble with the remove button that is created dynamically. It should removed the itself and the username textbox next to it. Instead it will always remove the top row that was added. Also when you click add a new user after you have clicked remove it doesn't automatically fill the blank space - it moves the new textbox and button to the bottom line.

Here is my code:

private void AddUserbtn_Click_1(object sender, EventArgs e)
{
    TextBox[] Username = new TextBox[n];
    Button[] Remove = new Button[n];

    int UsernameX, UsernameY, RemoveX, RemoveY;

    UsernameX = 346;
    UsernameY = 45;
    RemoveX = 946;
    RemoveY = 45;

    for (int i = 0; i < n; i++)
    {
        Username[i] = new TextBox();
        Username[i].Size = new Size(233, 26);
        Username[i].Location = new Point(UsernameX, UsernameY + space);
        Username[i].Font = new Font("Arial", 10);
        Username[i].Name = "Username" ;

        Remove[i] = new Button();
        Remove[i].Location = new Point(RemoveX, RemoveY + space);
        Remove[i].Text = "Remove";
        Remove[i].Font = new Font("Arial", 10);
        Remove[i].Size = new Size(95, 23);
        Remove[i].UseVisualStyleBackColor = true;
        Remove[i].Click += new EventHandler(Remove_Click);
        Remove[i].Name = "Remove";

        space += 35;
    }

    for (int i = 0; i < n; i++)
    {
        CaeUsersPanel.Controls.Add(Username[i]);
        CaeUsersPanel.Controls.Add(Remove[i]);
    }
}

private void Remove_Click(object sender, EventArgs e)
{
    CaeUsersPanel.Controls.Remove(CaeUsersPanel.Controls[("Username")]);
    CaeUsersPanel.Controls.Remove(CaeUsersPanel.Controls[("Remove")]);
}

Put a class variant to store Button - TextBox pair, and delete respectively. Quick tested code below - not fine tuned for memory leak / logic etc, just a sample code that fulfills your requirement.

Dictionary<Button, TextBox> pair = new Dictionary<Button, TextBox>(); // A dictionary to store the Button - TextBox pair

private void button1_Click(object sender, EventArgs e) {
    int n = 3; // Added for testing
    int space = 0; // Added for testing

    int UsernameX, UsernameY, RemoveX, RemoveY;

    UsernameX = 100; // Modified for testing
    UsernameY = 45;
    RemoveX = 400; // Modified for testing
    RemoveY = 45;

    for (int i = 0; i < n; i++) {
        var Username = new TextBox();
        Username.Size = new Size(233, 26);
        Username.Location = new Point(UsernameX, UsernameY + space);
        Username.Font = new Font("Arial", 10);
        Username.Name = "Username";

        var Remove = new Button();
        Remove.Location = new Point(RemoveX, RemoveY + space);
        Remove.Text = "Remove";
        Remove.Font = new Font("Arial", 10);
        Remove.Size = new Size(95, 23);
        Remove.UseVisualStyleBackColor = true;
        Remove.Click += new EventHandler(Remove_Click);
        Remove.Name = "Remove";

        Controls.Add(Username);
        Controls.Add(Remove);

        pair.Add(Remove, Username);

        space += 35;
    }
}
private void Remove_Click(object sender, EventArgs e) {
    Controls.Remove((Button)sender); // Removes the delete button
    Controls.Remove(pair[(Button)sender]); // Removes the textbox
    pair.Remove((Button)sender); // Removes the entry in dictionary
}

Update: Another version for better memory and logic matters. Also shifts up the rest of controls up if it's the OP's desire.

int n = 3; // Added for testing, probably you already have it somewhere
int space = 0; // Added for testing, probably you already have it somewhere

// Moved for logic
// Value modified for testing
int UsernameX = 100;
int UsernameY = 45;
int RemoveX = 400;
int RemoveY = 45;

int SpaceDelta = 35; // Added for logic

List<Button> RemoveButtons = new List<Button>();
List<TextBox> UsernameTextBoxes = new List<TextBox>();

private void button1_Click(object sender, EventArgs e) {

    Random rnd = new Random((int)DateTime.Now.Ticks); // Added for testing

    for (int i = 0; i < n; i++) {
        var Username = new TextBox();
        Username.Size = new Size(233, 26);
        Username.Location = new Point(UsernameX, UsernameY + space);
        Username.Font = new Font("Arial", 10);
        Username.Name = "Username";
        Username.Text = $"{(int)(rnd.NextDouble() * 100000)}"; // Added for testing

        var Remove = new Button();
        Remove.Location = new Point(RemoveX, RemoveY + space);
        Remove.Text = $"{(int)(rnd.NextDouble() * 100000)}";  // Modified for testing
        Remove.Font = new Font("Arial", 10);
        Remove.Size = new Size(95, 23);
        Remove.UseVisualStyleBackColor = true;
        Remove.Click += new EventHandler(Remove_Click);
        Remove.Name = "Remove";

        Controls.Add(Username);
        Controls.Add(Remove);

        RemoveButtons.Add(Remove);
        UsernameTextBoxes.Add(Username);

        space += SpaceDelta;
    }
}
private void Remove_Click(object sender, EventArgs e) {
    int idx = RemoveButtons.IndexOf((Button)sender);

    // Remove button
    RemoveButtons[idx].Dispose();
    RemoveButtons.RemoveAt(idx);

    // Remove textbox
    UsernameTextBoxes[idx].Dispose();
    UsernameTextBoxes.RemoveAt(idx);

    // Shift controls up
    for (int i = idx; i < RemoveButtons.Count; i ++) {
        RemoveButtons[i].Top -= SpaceDelta;
        UsernameTextBoxes[i].Top -= SpaceDelta;
    }

    space -= SpaceDelta;
}

Remove the two last created :

private void Remove_Click(object sender, EventArgs e)
{
    this.Controls.Remove(this.Controls[this.Controls.Count - 1]);
    this.Controls.Remove(this.Controls[this.Controls.Count - 1]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM