我有一个带有面板的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事件?如果没有,我的选择是什么?
请告知。
答案 0 :(得分:6)
pnlContent.Controls.Clear();
你必须非常小心这种方法,它不会按照你的想法做到。它确实不处理面板上的控件,它只是删除它们。控件继续存在,他们的窗口被托管到隐藏的“停车窗口”。准备搬回另一位家长。
在许多情况下,这种情况不会发生,控制将永远泄漏。在你的具体情况下它还不是很糟糕,你仍然可以参考控件。您的uc1
变量存储它。然而结果是它的Load事件不会再次触发,只发生一次。
因此,如果你真的需要启动Load事件,那么你应该以正确的方式执行此操作,实际上将控件放在面板上:
while (pnlContent.Controls.Count > 0) pnlContents.Controls[0].Dispose();
然后您必须创建任何usercontrol类型uc1
引用的 new 实例。然后,当您将Load事件添加到面板时,您将触发Load事件。
这个答案中另一个强有力的隐藏信息是非常可能根本不应该使用Load事件。在绝大多数情况下,Load事件处理程序中的代码属于构造函数。如果您需要知道Handle属性,或者需要确保计算布局以便知道控件的最终大小,则只需要Load。那很少见。
答案 1 :(得分:1)
我有一个像工具箱一样的控件,当用户按下切换按钮时,它会从另一个父控件中添加和删除。
我没有使用加载事件(仅在第一次将控件添加到其父控件集合时触发),而是使用 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
}
}
答案 2 :(得分:0)
我认为你可以做到:
uc1.load(this, null);
因为您只删除它,然后重新添加它。你不要重新初始化它。