我有一个WinForms表单(称之为'MyForm'),它承载一些WPF UI(通过ElementHost)。我在主UI线程的单独线程上显示此表单。
我希望'MyForm'保持在主应用程序窗口的顶部,所以我使用Show方法的Show(IWin32Window)重载来显示表单,传入的IWin32Window是主应用程序窗口。
窗口通过'启动器窗体'间接显示,启动器窗体是单独的STA线程(传递给Application.Run的线程)的“应用程序窗体”。原因是您在通过Application.Run启动表单时无法指定所有者窗口。
以下是启动MyForm的代码(用作STA线程的ThreadStart):
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.
}
'发射器'形式:
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);
}
}
这几乎可行。 'MyForm'停留在主应用程序窗口的顶部,但只有在我用工具提示鼠标悬停在WPF控件上之后。显示工具提示时,“MyForm”将消失在主应用程序窗口后面。当我在我的表单上鼠标悬停WinForms控件以显示其工具提示时,这不会发生 - 它似乎特定于WPF控件。
只有当MyForm是前景窗口时才会发生。
请注意,当我使用MyForm作为应用程序表单(跳过启动器)并覆盖MyForm的OnLoad方法以使用SetWindowLong设置其所有者时,我会遇到同样的问题。这是一种较少参与的方式,但我想使用一种不使用P-Invoke的机制来查看这是否会更好。两种方法都以同样的方式被打破。
更新 测试应用程序意味着此问题特定于在Visual Studio向导扩展中显示UI。我认为这使得它更加利基,甚至不太可能得到回答!
答案 0 :(得分:0)
以下MSDN文章是关于WinAPI调用的,但它希望能让您对不同线程之间的窗口激活有所了解(我假设您必须直接将P / Invoke引入WinAPI,除非您可以避免在多个线程上使用您的UI ):
(特别参见窗口焦点和激活注意事项部分)