【问题标题】:How do i know when my Control is done being initialized?我如何知道我的控件何时完成初始化?
【发布时间】:2012-02-17 22:33:38
【问题描述】:

我有一个 .NET 控件,用户可以将其放在表单上。

Visual Studio 创建一个InitializeComponent,从宿主窗体的构造函数中调用:

public EditItemForm()
{
   InitializeComponent();
}

这个自动生成的方法,在一个自动生成的文件中,根据设计器可序列化规则初始化我的控件。例如:

private void InitializeComponent()
{
   ...
   this.lvResults = new Contoso.Controls.VirtualGrobber();
   ...

   // 
   // lvResults
   // 
   this.lvResults.BorderStyle = System.Windows.Forms.BorderStyle.None;
   ...

   //FrobGrobberForm
   ...
   this.Controls.Add(this.lvResults);
   ...
}

我,一个坐在某人表单上的控件,如何知道所有设计器序列化何时完成,并且我“准备好了”?


在Delphi中,在控件中序列化的机制会自动调用每个控件的Loaded方法:

在从流中加载控件后对其进行初始化。

procedure Loaded; override;

说明

VCL 流系统调用 Loaded 在控件的表单加载到内存后自动 控件可以完成任何依赖于其他的初始化 表单中的对象。

【问题讨论】:

  • 您可以通过多种不同的方式来做到这一点。哪个是惯用的或合适的实际上取决于您要初始化的确切内容。当然,设计器并没有做任何神奇的事情,它只是在您的控件上设置属性。并且设计自定义控件的标准规则是属性应该能够以任何顺序设置,无论是由用户还是设计者。
  • 实现ISupportInitialize接口。
  • @HansPassant 我实现了 ISupportInitialize,并将代码放入 EndInit(),但它从未被调用。实施 ISupportInitialize 是否应该做点什么? 我收回它。一旦您构建了两次,设计者就会在InitializeComponent 期间添加对EndInit() 的调用。真的应该以答案的形式表达出来。

标签: .net winforms controls


【解决方案1】:

实现ISupportInitialize 接口。设置完所有组件的属性后,Visual Studio 会将代码添加到调用 EndInit 的表单设计器代码文件中。

【讨论】:

    【解决方案2】:

    假设您询问 WinForms Control 类:您可以覆盖 Control.OnControlCreated 方法。另一种选择是覆盖在创建基础图形对象时调用的Control.OnHandleCreated 方法。

    【讨论】:

      【解决方案3】:

      而且...您可以在 ParentChanged 事件中检测到它

      private void VirtualGrobber_ParentChanged(object sender, EventArgs e)
      {
          try
          {
              Form frm = this.FindForm();
              if (frm != null && !frm.IsDisposed)
                  frm.Load += new EventHandler(frm_Load);
          }
          catch (Exception ex)
          {
              //Do something
          }
      }
      
      private void frm_Load(object sender, EventArgs e)
      {
          //Do what you want
      }
      

      【讨论】:

        【解决方案4】:

        假设您希望在Control“就绪”时执行一些代码:

        如果您希望它在Control“准备好”时立即执行,甚至在显示表单之前:在表单构造函数中的InitializeComponent(); 之后添加该代码。 (这只是一种创建Control 等的方法。)

        如果您希望在显示表单时执行它,请添加:

        Shown += Form1_Shown;
        

        在表单的构造函数中,并且:

        void Form1_Shown(object sender, EventArgs e)
        {
            //code to execute.
        }
        

        在表单的类中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-02-09
          • 1970-01-01
          • 2022-08-13
          • 1970-01-01
          • 2023-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多