Reputation: 28586
I have an application that has a WinForm(myForm
).
In that WinForm there are a WPF UserControl(myWPF
).
In that WPF UserControl there are a WinForm UserControl(myWinCtrl
).
The myWinCtrl has a custom WinGrid(myWinGrid
).
myWinGrid
does internally a this.FindForm()
and.... does not find myForm
...
Is there a way to override the FindForm
method in order that it includes the possibility of a WPF intermediary layer?
myGrid => myWinFormUC => Host => WpfUC => Host => myWinForm
So, I need myGrid
finds myWinForm
Upvotes: 3
Views: 776
Reputation: 4855
This is a sample code based on Reed's idea
private Form FindOwnerThroughHandle(Control ctrl)
{
var ancestorHandle = GetAncestor(ctrl.Handle, GetAncestorFlags.GA_ROOT);
return Control.FromHandle(ancestorHandle) as Form;
}
private enum GetAncestorFlags : uint
{
// Retrieves the parent window.This does not include the owner, as it does with the GetParent function.
GA_PARENT = 1,
// Retrieves the root window by walking the chain of parent windows.
GA_ROOT = 2,
// Retrieves the owned root window by walking the chain of parent and owner windows returned by GetParent.
GA_ROOTOWNER = 3,
}
[DllImport("user32.dll", ExactSpelling = true)]
static extern IntPtr GetAncestor(IntPtr hwnd, GetAncestorFlags flags);
Upvotes: 0
Reputation: 564691
You could use PInvoke with GetAncestor to directly get the top level form containing your control.
At that point, you could compare the resulting IntPtr to the handles in each form of Application.OpenForms to find the actual Windows Forms Form instance.
A possible brute force approach could be to use Control.PointToScreen with the center of your control, then search your Application.OpenForms for any active forms containing that point. The tricky part would be handling if you had overlapping forms, but only one should be active, so if this is in response to a UI action, the active form at that location should be the correct form...
Upvotes: 1