I have a non-visual component which manages other visual controls.
I need to have a reference to the form that the component is operating on, but i don\'t know how
I found this solution which does not need the input. For C# I implemented it this way:
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
}
This way allows the set ParentForm by user, but it is set by parent form as Default.
I hope it helps you.
Try This ....
private Form GetParentForm(Control parent)
{
if (parent is Form)
return parent as Form;
return parent.FindForm();
}
Call GetParentForm(this.Parent)
from component
I use a recursive call to walk up the control chain. Add this to your control.
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
}
Edit: I see you modified your question as I was typing this. If it is a component, the constructor of that component should take it's parent as a parameter and the parent should pass in this when constructed. Several other components do this such as the timer.
Save the parent control as a member and then use it in the ParentForm property I gave you above instead of this.
You will have to set the parent container some how. Your component is just a class, that resides in memory just like everything else. It has no true context of what created it unless something tells you that it did. Create a Parent control property and set it.
Or simply derive from control and use FindForm(). Not all controls must have a visible component
Thanks Rob, I used your solution in a VB.Net program, looks like this:
''' <summary>
''' Returns the parent System.Windows.form of the control
''' </summary>
''' <param name="parent"></param>
''' <returns>First parent form or null if no parent found</returns>
''' <remarks></remarks>
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
Referenced it on my blog: http://www.dailycode.info/Blog/post/2012/07/03/How-to-get-a-user-controls-parent-form-(Windows-forms).aspx
I think you want to use the Site property of the IComponent. It's more or less an equivalent to the Parent property.