首页 > 解决方案 > Windows 窗体动态添加删除用户控件

问题描述

我有一个 Windows 表单应用程序,我需要允许用户在表单上添加尽可能多的电子邮件 ID

我希望能够在单击按钮时为电子邮件 ID 字段添加文本框控件。文本框应该是动态添加的,并且可以在表单上添加 N 个文本框。

同时在任何给定点用户应该能够删除添加的文本框。单击“保存”按钮后,所有“n”封电子邮件都需要存储在数据库中。

任何人都可以请建议如何在 Windows 表单应用程序中执行此操作吗?

标签: winformsdynamic

解决方案


您可能应该创建一个自定义用户控件来保存您的电子邮件地址和删除按钮。这样,您可以按删除按钮删除该电子邮件地址/控件。

然后你会希望你的主窗体有一个按钮来添加电子邮件地址(你的自定义控件的一个实例),然后是一个 FlowLayoutPanel 来保存你的客户控件。

您的自定义控件代码应类似于:

public class EmailAddressControl : UserControl
{
    public string EmailAddress
    {
        get
        {
            return(tbEmailTextBox.Text);
        }
        set
        {
            tbEmailTextBox.Text = value;
        }
    }

    public EmailAddressControl()
    {
        InitializeComponent();
    }

    public event EventHandler<EventArgs> RemoveEmailAddress;

    public void btnRemoveEmailAddress_Click(object sender, EventArgs e)
    {
        RemoveEmailAddress?.Invoke(this, EventArgs.Empty);
    }
}

我们在 UserControl 上有两个子控件,tbEmailTextBox一个是文本框,btnRemoveEmailAddress一个是按钮。tbEmailTextBox将保存您的用户输入的电子邮件地址。您可以从控件外部通过 EmailAddress 属性访问它。btnRemoveEmailAddress将触发该RemoveEmailAddress事件,该事件将告诉其订阅者它应该被关闭。

正如我之前所说,您的主窗体应该有一个FlowLayoutPanel和几个按钮。我们将调用的按钮btnAddEmail将电子邮件用户控件添加到屏幕和我们将调用的面板以及我们将调用flpEmailAddresses的第二个按钮btnSaveEmails,它将您的电子邮件保存到数据库(这些按钮不应是流程布局面板的子级 -主要是为了好看)。

您的主要代码形式如下所示:

public class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
    }

    public void btnAddEmail_Click(object sender, EventArgs e)
    {
        EmailAddressControl email = new EmailAddressControl();
        email.RemoveEmailAddress += RemoveEmailAddress;
        flpEmailAddresses.Controls.Add(email);
    }

    public void RemoveEmailAddress(object sender, EventArgs e)
    {
        EmailAddressControl email = sender as EmailAddressControl;
        email.RemoveEmailAddress -= RemoveEmailAddress;
        flpEmailAddresses.Controls.Remove(email);
        email.Dispose();
        email = null;
    }

    public void btnSaveEmails_Click(object sender, EventArgs e)
    {
        foreach(EmailAddressControl email in flpEmailAddresses.OfType<EmailAddressControl>())
        {
            databaseinstance.SaveEmail(email.EmailAddress);
        }
    }
}

在其中,btnAddEmail_Click我们正在创建您的新实例EmailAddressControl并订阅该RemoveEmailAddress事件,以便主窗体知道何时删除它。然后我们将它添加到flpEMailAddresses面板中。

当您的用户按下btnRemoveEmailAddress它时,它会RemoveEmailAddress在事件处理程序中触发由主窗体捕获的RemoveEmailAddress事件。在这个处理程序中,我们将 sender 对象强制转换为EmailAddressControl取消订阅 RemoveEmailAddress 事件(以避免内存泄漏并允许控件被垃圾收集),然后我们从flpEmailAddresses面板中删除控件并最终处理EmailAddressControl.

如果用户单击该btnSaveEmails按钮,则应用程序将遍历作为其子级的 EmailAddressControls,flpEmailAddresses并从每个控件中检索 EmailAddress 并将其发送到databaseinstance.SaveEmail. 我将留给您databaseinstance.SaveEmail(string emailaddress)自己实施。


推荐阅读