C# 何时启动和处置我的用户控件?

C# 何时启动和处置我的用户控件?,c#,.net,C#,.net,在winforms应用程序中,我有一个选项表单。表单有一个treview控件和一个panel控件。 根据treeview中的用户选择,我希望向panel控件加载/添加usercontrol。 我应该何时创建/启动usercontrols?在窗体load eventhandler上,还是在选择treeview节点后? 我是否应该在from closing eventhandler中处理usercontrols 这是我的代码: public partial class Options : Form

在winforms应用程序中,我有一个选项表单。表单有一个treview控件和一个panel控件。 根据treeview中的用户选择,我希望向panel控件加载/添加usercontrol。 我应该何时创建/启动usercontrols?在窗体load eventhandler上,还是在选择treeview节点后? 我是否应该在from closing eventhandler中处理usercontrols

这是我的代码:

public partial class Options : Form
{
    //usercontrols
    Connections _connections;
    Notifications _notifications;
    Proxy _proxy;

    private void Options_Load(object sender, EventArgs e)
    {
        treeViewOptions.ExpandAll();

        _connections = new Connections();
        _notifications = new Notifications();
        _proxy = new Proxy();
    }

    private void treeViewOptions_AfterSelect(object sender, TreeViewEventArgs e)
    {
        switch (treeViewOptions.SelectedNode.Name)
        {

            case "NodeConnection":
                ControlPanel.Controls.Clear();
                ControlPanel.Controls.Add(_connections);
                break;
            case "NodeNotifications":
                ControlPanel.Controls.Clear();
                ControlPanel.Controls.Add(_notifications);
                break;
            case "NodeProxy":
                ControlPanel.Controls.Clear();
                ControlPanel.Controls.Add(_proxy);
                break;
        }
    }
}

谢谢

是的,您需要修复此问题。现在您正在泄漏用户控件实例,这些实例将不会自动处理。他们的终结器也不负责这项工作。一段时间后,当您的程序消耗了10000个窗口句柄时,它将崩溃

让它看起来像这样:

private void treeViewOptions_AfterSelect(object sender, TreeViewEventArgs e)
{
    foreach (Control ctl in ControlPanel.Controls) ctl.Dispose();
    ControlPanel.Controls.Clear();

    switch (treeViewOptions.SelectedNode.Name)
    {

        case "NodeConnection":
            ControlPanel.Controls.Add(_connections);
            break;
        case "NodeNotifications":
            ControlPanel.Controls.Add(_notifications);
            break;
        case "NodeProxy":
            ControlPanel.Controls.Add(_proxy);
            break;
    }
}

解决方案:

public partial class Options : Form
{
    //usercontrols
    Connections _connections;
    Notifications _notifications;
    Proxy _proxy;

private void Options_Load(object sender, EventArgs e)
{
    treeViewOptions.ExpandAll();

    _connections = new Connections();
    _notifications = new Notifications();
    _proxy = new Proxy();
}

private void treeViewOptions_AfterSelect(object sender, TreeViewEventArgs e)
{
    ControlPanel.Controls.Clear();

    switch (treeViewOptions.SelectedNode.Name)
    {

        case "NodeConnection":

            ControlPanel.Controls.Add(_connections);
            break;
        case "NodeNotifications":

            ControlPanel.Controls.Add(_notifications);
            break;
        case "NodeProxy":

            ControlPanel.Controls.Add(_proxy);
            break;
    }
}

   private void Options_FormClosing(object sender, FormClosingEventArgs e)
    {

        _connections.Dispose();          
        _notifications.Dispose();
        _proxy.Dispose();

    }

}

好的,谢谢。我是否在正确的时间创建控件?在表单加载期间创建所有控件是正确的,还是应该在我选择的情况下创建它们?在表单关闭事件处理程序中处理这些控件不是更好吗?因为控件是在表单load eventhandler中创建的,这意味着如果用户在treview节点之间来回切换,则可以使用相同的控件。使用您的解决方案,每次用户选择一个新的treeview节点时,我都必须创建一个新的usercontrol实例,这肯定会降低性能?在动态创建时,您使用的系统资源要少得多。性能不应受到明显影响。成本是在控制绘画本身,创作是便宜的。使它们保持活动状态并使用Hide/Show在它们之间切换的一个功能是,以前在控件中输入的任何内容都会保留下来。可能是需要的,可能不是,这取决于。如果我没记错的话,Controls.Clear()将在内部调用每个移除的控件的Dispose()。@Anna-它没有。许多winforms程序员都陷入了一个令人讨厌的陷阱。泄漏需要一段时间才能使程序崩溃。