我在msdn上查找了winforms(找到here)的UserControl.Load事件并看到了这条警告消息:
创建UserControl的句柄时发生Load事件。 在某些情况下,这可能会导致Load事件发生更多 不止一次。例如,在UserControl时发生Load事件 加载,如果重新创建句柄,则再次加载。 (一种方式 通过调用RecreateHandle方法重新创建句柄。)To 如果Load事件发生了多次,你应该这样做 将任何一次初始化代码放在UserControl构造函数中 而不是Load事件处理程序。此外,您不应该添加数据 绑定到Load事件处理程序中的UserControl。
我的问题是,除了对RecreateHandle的显式调用之外,还会导致为UserControl重新创建句柄吗?在阅读本文之前,我总是把任何只应该在Load事件中发生过一次的事情。另外(从最后一句),添加数据绑定的最佳位置在哪里?如果我不打电话给RecreateHandle,这真的很重要吗?
答案 0 :(得分:7)
是的,这是可能的。它是由本机Windows CreateWindowEx()API函数的问题引起的。该调用指定窗口的样式位。这些相同的样式位也作为Control的属性公开。问题是,更改该属性需要再次调用CreateWindowEx()。控件的本机Windows窗口将被销毁并重新创建。这有副作用,其中一个是让Load事件再次运行。
使用代码示例演示它:
public partial class UserControl1 : UserControl {
public UserControl1() {
InitializeComponent();
}
public void TriggerRecreate() {
if (this.RightToLeft == System.Windows.Forms.RightToLeft.Yes)
this.RightToLeft = System.Windows.Forms.RightToLeft.No;
else this.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
}
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
Console.WriteLine("onload");
}
}
在窗体上编译并删除控件。添加一个按钮:
private void button1_Click(object sender, EventArgs e) {
userControl11.TriggerRecreate();
}
并观察每次单击按钮时“输出”窗口显示“onload”。
对于将执行此操作的UserControl,RightToLeft属性是我能想到的唯一属性。表格还有很多。但是,该类具有专用代码来防止其OnLoad方法多次运行。不知道为什么他们没有为UserControl做这个,可能是因为它是如此罕见。随意忽略它。并且总是喜欢构造函数而不是Load事件,除非你关心窗口大小。