重新创建UserControl句柄的频率是多少?

时间:2011-07-22 20:59:56

标签: .net winforms events user-controls

我在msdn上查找了winforms(找到here)的UserControl.Load事件并看到了这条警告消息:

  

创建UserControl的句柄时发生Load事件。   在某些情况下,这可能会导致Load事件发生更多   不止一次。例如,在UserControl时发生Load事件   加载,如果重新创建句柄,则再次加载。 (一种方式   通过调用RecreateHandle方法重新创建句柄。)To   如果Load事件发生了多次,你应该这样做   将任何一次初始化代码放在UserControl构造函数中   而不是Load事件处理程序。此外,您不应该添加数据   绑定到Load事件处理程序中的UserControl。

我的问题是,除了对RecreateHandle的显式调用之外,还会导致为UserControl重新创建句柄吗?在阅读本文之前,我总是把任何只应该在Load事件中发生过一次的事情。另外(从最后一句),添加数据绑定的最佳位置在哪里?如果我不打电话给RecreateHandle,这真的很重要吗?

1 个答案:

答案 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事件,除非你关心窗口大小。