带有Win32父窗口的WPF OpenFileDialog;窗户在关闭时没有重新获得焦点

时间:2011-04-12 17:04:59

标签: c# wpf winapi c++-cli openfiledialog

我有一个c ++ windows app调用c ++ / cli库,它调用托管库。托管库使用WinF窗口拥有的WPF窗口父级调用OpenFileDialog.Show。我没有找到更好的方法来做到这一点,我在这里阅读的所有资源以及搜索google和social.msdn都建议我做我正在做的事情。

对话框打开很好,但是当我点击取消按钮时,应用程序完全失去焦点。我不确定为什么会这样,但我似乎无法阻止它。我尝试了许多不同的事情无济于事。

如果我只是在不创建WPF窗口的情况下启动OpenFileDialog,我就没有看到问题。 如果我没有设置WPF窗口的所有者,我没有看到问题。如果我调用OpenFileDialog.Show并且不传递父节点,但仍然创建WPF窗口并设置其所有者,我仍然会看到问题。

我能够破解它在失去焦点后将父应用程序窗口设置为前景,但我不想这样做。

我已经为我的方案上传了一个小例子解决方案,说明了问题:

http://dl.dropbox.com/u/26054523/MixedExample.zip

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:0)

您是否尝试过反转托管方案?现在,它听起来像是你的非托管 - > bridge-> managed-> WPF-> Winforms。也许你可以使用ElementHost来{managed-> WinForms-> WPF http://msdn.microsoft.com/en-us/library/ms742215.aspx

通过这种方式,WPF窗口将只是WinForms应用程序的子控件,对于焦点切换可能会更好。 WinForms控件并不能直接与WPF应用程序一起使用,正如您所指出的那样,正在使用两种不同的UI线程设置。

答案 1 :(得分:0)

我知道这是一个老帖子,但我认为这是一个常见的问题,我有一个很好的答案。如果你有一个名为ParentWindow的Win32窗口父窗口和一个名为WPFChild的WPF子窗口,你可以这样做:

using System.Windows.Interop;

void OpenWindow()
{
    WPFChildWindow WPFChild = new WPFChildWindow();
    WindowInteropHelper helper = new WindowInteropHelper(WPFChild)
    {
        Owner = new NativeWindowWrapper(ParentWindow.Hwnd).Handle
    };
    bool? ret = _stepsForm.ShowDialog();
}

这将导致子窗口保持在父窗口的顶部并作为对话框起作用。请记住,WPF窗口不会返回DialogResult,而是返回可以为空的bool。

NativeWindow包装器是一个简单的类,它将int转换为IntPtr。它实际上来自位于此处的.net Excel ref编辑项目:How to code a .NET RefEdit ControlT