2011-09-23 68 views
0

我正在创建一个自定义C#控件(窗体的标题栏)。一个表单只能有一个标题栏,这就是为什么我想知道一些事情:当用户(程序员)将我的标题栏添加到他的表单时,是否有任何方法可以检查ParentForm是否已经包含我的标题栏,如果可以的话我取消添加我的控制的另一个实例?检查自定义控件是否已添加到窗体中

我知道如何执行检查以查看ParentForm包含的控件类型,但是当我的控件从工具箱放置到窗体时以及如何在必要时“取消”控件布局时引发了什么事件?

+0

您是否关注使用设计器或手动添加代码的人? – SLaks

+0

设计师和代码! – guest86

回答

2

您应该使用read in-depth关于在.NET中提供的designer technologies,因为这些不是我称之为生产就绪的示例。然而,这给你一个坚实的开始,并且这两个代码片段都能完成你所要求的功能。

对于设计时,可以覆盖设计的网站在你的控制,并做到以下几点:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Drawing; 
using System.Data; 
using System.Text; 
using System.Windows.Forms; 
using System.ComponentModel.Design; 
using System.Diagnostics; 

namespace WindowsFormsControlLibrary1 { 
    public partial class DebugControl : UserControl { 
     public DebugControl() { 
      InitializeComponent(); 
     } 

     public override ISite Site 
     { 
      get 
      { 
       return base.Site; 
      } 
      set 
      { 
       base.Site = value; 
       IComponentChangeService service = (IComponentChangeService)GetService(typeof(IComponentChangeService)); 
       service.ComponentAdding += (sender, e) => { 
        IDesignerHost host = (IDesignerHost)value.Container; 
        Component component = (Component)host.RootComponent; 
        if (component as Form != null) 
        { 
         Form form = (Form)component; 
         foreach (Control c in form.Controls) 
         { 
          if (c.GetType() == this.GetType()) 
          { 
           throw new System.ArgumentException("You cannot add two of these controls to a form!"); 
          } 
         } 
        } 
       }; 
      } 
     } 
    } 
} 

对于您的形式运行时,您可以覆盖OnControlAdded并执行以下操作:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 
using System.Diagnostics; 
using WindowsFormsControlLibrary1; 

namespace WindowsFormsApplication1 { 
    public partial class Form1 : Form { 
     public Form1() { 
      InitializeComponent(); 
     } 

     protected override void OnShown(EventArgs e) 
     { 
      Controls.Add(new DebugControl()); 
     } 

     protected override void OnControlAdded(ControlEventArgs e) 
     { 
      base.OnControlAdded(e); 
      if (e.Control.GetType() == typeof(DebugControl)) 
      { 
       int count = 0; 
       foreach (Control c in Controls) 
       { 
        if (c is DebugControl) 
        { 
         count++; 
        } 
       } 
       if (count > 1) 
       { 
        Controls.Remove(e.Control); 
        Debug.Assert(false, "Cannot add two of these controls!"); 
       } 
      } 
     } 
    } 
} 

有多种方法可以做到这一点,但这些都是粗糙的例子,介意你。阅读关于.NET框架的设计时支持,它非常​​丰富,并且有大量文档。另一种方法是实现自定义设计器并实现CanBeParentedTo和CanParent,但是请注意,当您的控件是从ToolBox到您的窗体的药物时,CanBeParentedTo不会被调用。

+0

干得不错,我对此毫不知情! :) tnx – guest86

+0

您可以通过为您的控件和表单实现自定义设计器来实现同样的目的。问题在于表单使用BCL内部的FormDocumentDesigner,因此您必须重新创建相当多的工作。这是一个体面的方法,只需很少的工作。 –

0

您可以使用Controls收集有效的form

0

处理ParentChanged事件,检查父级的Controls,并在必要时抛出异常。

相关问题