【问题标题】:C# winforms dynamically created button controlsC# winforms 动态创建按钮控件
【发布时间】:2017-06-26 15:09:38
【问题描述】:

我有一个添加用户按钮,当用户单击它时,它会动态添加一个删除按钮和一个用户名文本框。用户可以随意点击按钮多次,控件将继续添加。

我在使用动态创建的删除按钮时遇到问题。它应该删除它本身和它旁边的用户名文本框。相反,它将始终删除添加的第一行。此外,当您单击删除后单击添加新用户时,它不会自动填充空白空间 - 它将新文本框和按钮移动到底线。

这是我的代码:

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")]);
}

【问题讨论】:

  • 嗨@Julie 我有一个问题,当您单击添加的按钮时,它应该自行删除?
  • 添加用户按钮将始终存在。当您单击添加时,它会创建一个新的文本框和按钮,当您单击新按钮时,它应该删除自身和新的文本框。但是添加按钮会一直存在
  • 所有这些控件都具有相同的名称。所以按名称删除是行不通的。您可以从 sender 参数中获取对按钮的引用。考虑使用 Tag 属性来存储对文本框的引用。 Controls.Remove() 还不够好,你必须使用 Dispose() 才能真正摆脱控件。
  • 为什么不创建文本框和按钮的用户控件。然后你可以处理适当的用户控件,去掉按钮和文本框。

标签: c# winforms


【解决方案1】:

放置一个类变体来存储Button - TextBox 对,并分别删除。下面的快速测试代码 - 没有针对内存泄漏/逻辑等进行微调,只是满足您要求的示例代码。

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
}

更新:更好的内存和逻辑的另一个版本很重要。如果这是 OP 的愿望,也会将其余控件上移。

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

【讨论】:

  • 删除控件并不会丢弃它。如果您释放控件,它将自动从控件集合中删除。
  • @LarsTech 正如我所说,我并没有为内存泄漏而烦恼,只是专注于功能。 PS,pair.Remove((Button)sender)会配置控件吗?
  • 不,不会的。您只需在控件上调用 Dispose。我忽略了您的免责声明,因为从长远来看,您的回答对用户没有帮助。
  • 使用此代码没有任何反应,添加用户按钮甚至不起作用。我不知道为什么
  • @Julie,你注意到我改变了 X 个位置吗?它不适合我的屏幕。所以它实际上可能会添加到您的表单中,但不会出现在可见区域中。
【解决方案2】:

删除最后创建的两个:

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]);
}

【讨论】:

  • 这删除了页面上的所有控件
猜你喜欢
  • 2020-10-30
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 2020-04-07
  • 1970-01-01
  • 1970-01-01
  • 2018-06-17
相关资源
最近更新 更多