【问题标题】:Custom Designer class for a .NET Windows Form issue.NET Windows 窗体问题的自定义设计器类
【发布时间】:2010-10-28 22:01:42
【问题描述】:

我已经实现了一个继承自 DocumentDesigner 的自定义设计器类。 .NET Framework 中的标准 Form 类使用 FormDocumentDesigner 类(也继承自 DocumentDesigner),但由于此类是内部的,因此无法从它继承并自定义其行为,我使用反射器复制了此类中的逻辑并插入它在我的自定义设计器类中(以便我的表单的默认设计时行为符合标准表单)。

除了一件事之外,一切都很好:在我的自定义设计器类的 Initialize 方法中,我想插入一个 ToolStrip 控件,以便在设计时每次打开我的表单时,该控件都是可见且可编辑的。问题是每次在设计器中关闭并重新打开窗体时都会调用 Initialize 方法,这会导致每次创建 ToolStrip 控件的新实例并将其添加到窗体的 Controls 集合中。我正在寻找一种方法来检查代码中是否已经有一个 ToolStrip 控件序列化并避免添加另一个。

直到现在才发现可以使用IDesignerHost的LoadComplete事件,检查Form的Controls集合中是否有ToolStrip。但是,如果有更好的想法,我们将不胜感激。

感谢您的宝贵时间! :-)

【问题讨论】:

    标签: c# .net winforms custom-controls design-time


    【解决方案1】:

    嗯,LoadComplete 事件是正确的点。我通常检查 Loading 属性以检查 Initialize 是在加载时发生还是在加载后被调用。

    IDesignerHost _host;
    Form _form;
    
    public override void Initialize(System.ComponentModel.IComponent component)
    {
      _form = component as Form;
      _host = (IDesignerHost)this.GetService(typeof(IDesignerHost));
      if (_host != null)
      {      
       if (_host.Loading)
       {
         _host.LoadComplete += new EventHandler(_host_LoadComplete);
       }
       else
       {
         initializeForm();
       }
      }
    }
    
    void _host_LoadComplete(object sender, EventArgs e)
    {
      _host.LoadComplete -= new EventHandler(_host_LoadComplete);
      initializeForm();
    }
    
    void initializeForm()
    {
       if (_form!= null)
       {
          ...
       }
    }
    

    另一种方法是创建一个可以放入表单的组件并为该组件创建一个设计器,而不是重新创建 FormDesigner。 从组件设计器中,您可以使用 _host.RootComponent 属性获取父表单。

    【讨论】:

      猜你喜欢
      • 2014-11-14
      • 1970-01-01
      • 2011-09-03
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 2020-07-01
      • 1970-01-01
      • 2019-05-27
      相关资源
      最近更新 更多