简体   繁体   English

UserControl Load事件在Winform中引发一次

[英]UserControl Load event raised once in Winform

I have a Winform with a panel that loads different user controls depending on user inputs. 我有一个带有面板的Winform,它根据用户输入加载不同的用户控件。

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

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

What I notice is that when I clear pnlContent and re-add uc1, the uc1's Load event doesn't get triggered, ie uc1's Load event only gets triggered in the very first time uc1 gets added to the pnlContent. 我注意到的是,当我清除pnlContent并重新添加uc1时,不会触发uc1的Load事件,即uc1的Load事件仅在uc1首次添加到pnlContent中时才被触发。

Is there a way to have the Load event always triggered every time the user control gets added to the panel? 有没有办法在每次将用户控件添加到面板时始终触发Load事件? If not, what are my options? 如果没有,我有什么选择?

Please advise. 请指教。

  pnlContent.Controls.Clear();

You have to be very careful with this method, it doesn't do what you think it does. 你必须非常小心这种方法,它不会做你认为它做的。 It does not dispose the controls on the panel, it merely removes them. 处置面板上的控件,它只是删除它们。 The controls go to live on, their windows are hosted to the hidden "parking window". 控件继续存在,他们的窗口被托管到隐藏的“停车窗口”。 Ready to be moved back to another parent. 准备搬回另一位家长。

In many cases that does not happen and the control will leak forever. 在许多情况下,这种情况不会发生,控制将永远泄漏。 In your specific case it isn't quite that bad yet, you still have a reference to the control. 在你的具体情况下它还不是很糟糕,你仍然可以参考控件。 Your uc1 variable stores it. 您的uc1变量将其存储。 The consequence however is that its Load event doesn't fire again, that only happens once. 然而结果是它的Load事件不会再次触发,只发生一次。

So if you really need that Load event to fire then you should do this the proper way, actually dispose the controls on the panel: 因此,如果您确实需要启动Load事件,那么您应该以正确的方式执行此操作,实际上将控件放在面板上:

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

And then you have to create a new instance of whatever usercontrol type uc1 references. 然后你必须创建任何usercontrol类型uc1引用的实例。 You'll then get the Load event to fire when you add it to the panel. 然后,当您将Load事件添加到面板时,将触发Load事件。

Another strong hidden message in this answer is that it is very likely that you shouldn't be using the Load event at all. 这个答案中另一个强有力的隐藏信息是你可能根本不应该使用Load事件。 In the vast majority of cases, code in the Load event handler belongs in the constructor. 在绝大多数情况下,Load事件处理程序中的代码属于构造函数。 You only need Load if you need to know the Handle property or need to be sure that layout was calculated so that the final size of the control is known. 如果您需要知道Handle属性,或者需要确保计算布局以便知道控件的最终大小,则只需要Load。 That's rare. 那很少见。

I have a control that acts like a toolbox, which is added and removed from another parent control as the user push a toggle button. 我有一个像工具箱一样的控件,当用户按下切换按钮时,它会从另一个父控件中添加和删除。

Instead of using the Load event (that triggers only the first time the control is added to its parent controls collection), I use the ParentChanged event. 我没有使用Load事件(仅在第一次将控件添加到其父控件集合时触发),而是使用ParentChanged事件。

Then I check the Parent property: if it is null, that means the control has been removed from its parent collection. 然后我检查Parent属性:如果它为null,则表示该控件已从其父集合中删除。 If it is not, the control has just been added. 如果不是,则刚刚添加了控件。

private void MyUserControl_ParentChanged(object sender, EventArgs e)
{
    try
    {
        if (this.Parent != null) 
        {
            // Perform initializations
        }
    }
    catch (Exception ex)
    {
        // Do my normal exception handling
    }
}

I think you can do: 我认为您可以:

uc1.load(this, null);

Because you only remove it, and add it again. 因为您仅将其删除,然后再次添加。 You dont reinitialize it. 您不重新初始化它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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