获取组件的父表单

我有一个非可视组件来管理其他视觉控件。

我需要引用组件正在运行的表单,但我不知道如何获取它。

我不确定添加一个构造函数与父指定为控件,因为我希望组件只是被放入设计器中工作。

另一个想法是让父母的财产作为控制,默认值为’我’

任何建议都会很棒

编辑:

为了澄清,这是一个组件 ,而不是一个控件 ,请参见此处: ComponentModel.Component

[重要的是要理解下面的ISite技术仅适用于设计时。 因为ContainerControl是公共的并且被赋值,所以VisualStudio将编写在运行时设置它的初始化代码。 站点在运行时设置,但你不能从它获取ContainerControl]

这是一篇描述如何为非可视组件执行此操作的文章 。

基本上,您需要向组件添加属性ContainerControl:

public ContainerControl ContainerControl { get { return _containerControl; } set { _containerControl = value; } } private ContainerControl _containerControl = null; 

并覆盖Site属性:

 public override ISite Site { get { return base.Site; } set { base.Site = value; if (value == null) { return; } IDesignerHost host = value.GetService( typeof(IDesignerHost)) as IDesignerHost; if (host != null) { IComponent componentHost = host.RootComponent; if (componentHost is ContainerControl) { ContainerControl = componentHost as ContainerControl; } } } } 

如果这样做,ContainerControl将被初始化为由设计者引用包含的表单。 链接的文章更详细地解释了它。

查看如何执行操作的好方法是查看.NET Framework中的类型的实现,这些类型的行为与您使用Lutz Reflector等工具类似。 在这种情况下,System.Windows.Forms.ErrorProvider是一个很好的例子:需要知道其包含Form的Component。

我使用递归调用来走控制链。 将此添加到您的控件。

 public Form ParentForm { get { return GetParentForm( this.Parent ); } } private Form GetParentForm( Control parent ) { Form form = parent as Form; if ( form != null ) { return form; } if ( parent != null ) { // Walk up the control hierarchy return GetParentForm( parent.Parent ); } return null; // Control is not on a Form } 

编辑:我看到你在输入时修改了你的问题。 如果它是一个组件,那么该组件的构造函数应该将它的父元素作为参数,父元素应该在构造时传入它。 其他几个组件也会这样做,例如计时器。

将父控件保存为成员,然后在我上面给出的ParentForm属性中使用它而不是这个。

您将不得不设置父容器的方式。 你的组件只是一个类,它就像其他所有类一样驻留在内存中。 它没有创造它的真实背景,除非有东西告诉你它做了。 创建父控件属性并进行设置。

或者只是从控件派生并使用FindForm()。 并非所有控件都必须具有可见组件

如果组件正在管理其他可视控件,那么您应该能够通过它们访问父级。

我发现这个解决方案不需要输入。 对于C#我以这种方式实现它:

 public partial class RegistryManager : Component, ISupportInitialize { private Form _parentForm; public Form ParentForm { get { return _parentForm; } set { _parentForm = value; } } // Etc.... #region ISupportInitialize public void BeginInit() { } public void EndInit() { setUpParentForm(); } private void setUpParentForm() { if (_parentForm != null) return; // do nothing if it is set IDesignerHost host; if (Site != null) { host = Site.GetService(typeof(IDesignerHost)) as IDesignerHost; if (host != null) { if (host.RootComponent is Form) { _parentForm = (Form)host.RootComponent; } } } } #endregion } 

这种方式允许用户设置ParentForm,但它由父表单设置为Default。

我希望它对你有所帮助。

我想你想使用IComponent的Site属性。 它或多或少等同于Parent属性。

谢谢Rob,我在VB.Net程序中使用了您的解决方案,如下所示:

 '''  ''' Returns the parent System.Windows.form of the control '''  '''  ''' First parent form or null if no parent found '''  Public Shared Function GetParentForm(ByVal parent As Control) As Form Dim form As Form = TryCast(parent, Form) If form IsNot Nothing Then Return form End If If parent IsNot Nothing Then ' Walk up the control hierarchy Return GetParentForm(parent.Parent) End If ' Control is not on a Form Return Nothing End Function 

在我的博客上引用它: http : //www.dailycode.info/Blog/post/2012/07/03/How-to-get-a-user-controls-parent-form-( Windows-forms) .aspx

试试这个 ….

 private Form GetParentForm(Control parent) { if (parent is Form) return parent as Form; return parent.FindForm(); } 

从组件调用GetParentForm(this.Parent)

如果组件相关Form是活动Form您可以通过Form.ActiveForm获取它。

以上的改进是:

 public static Form ParentForm(this Control ctrl) => ctrl as Form ?? ctrl.FindForm();