views:

32

answers:

3

Is there a way, when creating a WinForms Custom Control/User Control, to get a reference at runtime to the form the control is placed on, so as to access various properties of that form? I would rather not pass a reference to the form into the constructor of the control, as, for various reasons, I need to keep a default constructor with no parameters.

One example: I have several Custom Controls that encapsulate Win32 API calls, and some of the calls require Window handles to be passed as parameters. I would like to be able to retrieve the handle of the containing form so I can pass it to the API function.

Another example: I have a Custom Control that provides "toast"-style user notifications. I would like to have the option of opening the notification form in a location relative to the location of the main application form, such as centered on the main window, off to the right, etc. This is not possible, obviously, without knowing the coordinates of the main application's window.

I could resort to using FindWindowEx()-type API calls in some cases, but that feels like a kludge, and would not work in all cases.

Does anyone know if this is possible?

A: 

You want Control.Parent, which returns the parent control. To get the form, simply call parent on all your parent controls until you hit a System.Windows.Forms.Form.

Billy ONeal
This looks like it would work, but I was looking for something simple that wouldn't require a loop, etc.
AndrewC
@AndrewC: If a loop like that isn't simple then you have other problems besides trying to get the topmost control.
Billy ONeal
:-) I meant a single call to a property, versus several iterations of a loop. Which is simpler to you? Perhaps "less code" would have been more accurate?
AndrewC
A: 

You can use Control.TopLevelControl property.

max
This looks promising. I will try it.
AndrewC
This works well and simply. Thanks.
AndrewC
A: 

Try the FindForm method. Be aware that it will return null if called in your control's constructor.

If you can wait until the OnParentChanged event, FindForm will return a reference to the parent form then.

adrift
This looks like it would work, but I was looking for something simple that wouldn't require a loop, etc.
AndrewC