3

我有一个带有面板的 Winform,该面板根据用户输入加载不同的用户控件。

// to load a user control
pnlContent.Controls.Add(uc1);

// to change to different user control
pnlContent.Controls.Clear();
pnlContent.Controls.Add(uc2);

我注意到的是,当我清除 pnlContent 并重新添加 uc1 时,不会触发 uc1 的 Load 事件,即 uc1 的 Load 事件只会在 uc1 第一次添加到 pnlContent 时触发。

有没有办法在每次将用户控件添加到面板时始终触发 Load 事件?如果没有,我有什么选择?

请指教。

4

3 回答 3

6
  pnlContent.Controls.Clear();

你必须非常小心这种方法,它不会像你认为的那样做。它不处理面板上的控件,它只是删除它们。控件继续运行,它们的窗口托管在隐藏的“停车窗口”中。准备搬回另一位父母。

在许多情况下,这不会发生,并且控制将永远泄漏。在您的特定情况下,它还没有那么糟糕,您仍然可以引用控件。您的uc1变量存储它。然而,结果是它的 Load 事件不会再次触发,只会发生一次。

因此,如果您确实需要触发 Load 事件,那么您应该以正确的方式执行此操作,实际处理面板上的控件:

 while (pnlContent.Controls.Count > 0) pnlContents.Controls[0].Dispose();

然后您必须创建任何用户控件类型引用的新实例。uc1然后,当您将 Load 事件添加到面板时,您将触发它。

此答案中另一个强烈的隐藏信息是,您可能根本不应该使用 Load 事件。在绝大多数情况下,Load 事件处理程序中的代码属于构造函数。仅当您需要知道 Handle 属性或需要确保计算布局以便知道控件的最终大小时才需要 Load。这是罕见的。

于 2013-06-26T15:47:36.950 回答
1

我有一个类似于工具箱的控件,当用户按下切换按钮时,它会从另一个父控件中添加和删除。

我没有使用Load事件(仅在控件第一次添加到其父控件集合时触发),而是使用ParentChanged事件。

然后我检查 Parent 属性:如果它为 null,则表示控件已从其父集合中删除。如果不是,则该控件刚刚添加。

private void MyUserControl_ParentChanged(object sender, EventArgs e)
{
    try
    {
        if (this.Parent != null) 
        {
            // Perform initializations
        }
    }
    catch (Exception ex)
    {
        // Do my normal exception handling
    }
}
于 2013-07-30T06:22:46.567 回答
0

我认为你可以这样做:

uc1.load(this, null);

因为您只删除它,然后再次添加它。你不重新初始化它。

于 2013-06-26T15:26:54.933 回答