I have a WinForms form (call it 'MyForm') that hosts some WPF UI (via ElementHost). I show this form on a separate thread from the main UI thread.
I want 'MyForm' to remain on top of the main application window, so I am showing the form using the Show(IWin32Window) overload of the Show method, with the passed-in IWin32Window being the main app window.
The window is shown indirectly via a 'launcher form' which is the 'application form' of the separate STA thread (the one passed in to Application.Run). The reason for this is that you can't specify an owner window when launching a form via Application.Run.
Here is the code to launch MyForm (used as the ThreadStart for an STA thread):
void MyWindowThread()
{
myForm = new MyForm();
var launcherForm = new LauncherForm(myForm, mainWindow);
Application.Run(new ApplicationContext(launcherForm));
// launcherForm will Show myForm when it itself is shown.
}
The 'launcher' form:
public partial class LauncherForm : Form
{
private readonly MyForm _myForm;
private readonly IWin32Window _mainWindow;
public WizardUILauncherForm(MyForm myForm, IWin32Window mainWindow)
{
_myForm = myForm;
_mainWindow = mainWindow;
InitializeComponent();
}
protected override void OnShown(EventArgs e)
{
// show the actual form that the user will interact with, on top of mainWindow.
_myForm.Show(_mainWindow);
}
}
This almost works. 'MyForm' stays on top of the main app window, but only until I mouse over a WPF control with a tooltip. When the tooltip is shown, 'MyForm' disappears behind the main application window. This doesn't happen when I mouseover a WinForms control on my form to display its tooltip - it seems specific to WPF controls.
It also only happens when MyForm is the foreground window.
Note that I get the same problem when I use MyForm as the application form (skipping out the launcher) and override MyForm's OnLoad method to set its owner using SetWindowLong. This is a less involved way of doing it, but I wanted to use a mechanism that didn't use P-Invoke, to see if this would work better. Both methods are broken in the same way.
Update A test application implies that this problem is specific to showing UI in a Visual Studio wizard extension. Which I suppose makes it even more niche and even less likely to be answered!