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

问题描述:

我有一个C++ windows应用程序调用到调用到托管库的C++/cli库中。托管库调用OpenFileDialog.Show与Win32窗口所拥有的WPF窗口父级。我还没有找到更好的方法来做到这一点,我在这里阅读的所有资源和搜索谷歌和social.msdn建议做我在做什么。带有Win32父窗口的WPF OpenFileDialog;窗口关闭时没有重新获得焦点

对话框打开很好,但是当我点击取消按钮时,应用程序完全失去焦点。我不知道为什么会发生,但我似乎无法让它停止。我已经尝试了许多不同的东西无济于事。

如果我只是启动OpenFileDialog而不创建一个WPF窗口,我没有看到问题。 如果我没有设置WPF窗口的所有者,我看不到问题。如果我调用OpenFileDialog.Show并且不通过父项,但仍然创建WPF窗口并设置它的所有者,我仍然会看到问题。

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

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

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

任何帮助,将不胜感激。

+0

您是否尝试过在同一个线程上运行对话框? WinForms和Win32都是单线程的。它可能不喜欢你从另一个线程打开对话框。 – 2011-04-12 18:04:29

+0

是的,我有,它不会允许它。在另一个线程中打开的原因是因为WPF似乎想要在STA线程中运行。 – Jay 2011-04-12 18:27:26

+0

我有一个与C#类似的问题。出于某种原因,一旦OpenFileDialog被解除(通过OK或取消)程序失去焦点。 – Superbest 2012-04-07 02:18:38

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

这样,WPF窗口就会成为WinForms应用程序的子控件,对于焦点开关来说可能会更好。 WinForms控件并非真正用于直接与WPF应用程序一起工作,而是使用了两种不同的UI线程设置。

+0

鉴于非托管代码库的规模和复杂性,这是一个重大变化。此外,没有任何WinForms。目标是非托管窗口只调用托管WPF。 – Jay 2011-04-13 11:33:25

+0

很抱歉听到这个消息。在工作中,我们或多或少直接在WPF中记录了打开的文件对话框,以便与我们的窗口系统一起工作。有一种痛苦是没有更好的股票期权,我认为它是WPF的一般问题之一:股票对话框可能会非常棘手,除非您编码自己,然后他们很多工作。 – 2011-04-16 23:11:31

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

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,而是返回一个可为空的布尔值。

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