【发布时间】:2009-05-08 14:06:16
【问题描述】:
我有一个承载一些 WPF UI(通过 ElementHost)的 WinForms 表单(称为“MyForm”)。我在与主 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。我想这会让它更加利基,甚至更不可能被回答!
【问题讨论】: