从最内部的WPF用户控件获取父窗口

bvjxkvbb  于 2022-12-24  发布在  其他
关注(0)|答案(2)|浏览(471)

我有一个WPF用户控件,比如说UCInner,它包含一个WPF弹出窗口。UCInner用于另一个WPF用户控件,比如说UCOuter。
UCOuter嵌入在元素主机中(元素主机.子级= UCOuter)。
最后,UCOuter嵌入在Outlook VSTO自定义任务窗格中,后者用于winforms应用程序(Outlook VSTO加载项)。
因此,从最内部的WPF控件UCInner,我想获得父窗口。我尝试了一些替代方法,但没有成功,我总是得到null或异常:

Window w = Window.GetWindow(myPopup);
Window w = Window.GetWindow(UCInner);

我也试过解释here和这个one

  • 已更新-另一次尝试

我已经尝试了下面的代码,我可以成功地得到窗口句柄,但现在从句柄我需要得到窗口对象。

dynamic activeWindow = Globals.ThisAddIn.Application.ActiveWindow();
Microsoft.VisualStudio.OLE.Interop.IOleWindow win = activeWindow as Microsoft.VisualStudio.OLE.Interop.IOleWindow;

IntPtr handle;
win.GetWindow(out handle);

为了得到Window对象,我尝试了基于Window句柄的方法:

System.Windows.Interop.HwndSource hwndSource = System.Windows.Interop.HwndSource.FromHwnd(handle);

Window w = hwndSource.RootVisual as Window;

但这不起作用,hwndSource为空。

u0njafvf

u0njafvf1#

如果您需要找出正确的父窗口来显示您自己的WPF窗口,请将Application.ActiveWindow强制转换为IOleWindowApplication.ActiveWindow可以返回ExplorerInspector,它们都支持IOleWindow)并调用IOleWindow.GetWindow。创建WindowInteropHelper类的示例,并将Outlook窗口句柄指定为父类:

if (outlookHwnd != IntPtr.Zero)
{
    WindowInteropHelper helper = new WindowInteropHelper(YourDialogWindow);
    helper.Owner = outlookHwnd;
    YourDialogWindow.ShowInTaskbar = false;
}
ou6hu8tu

ou6hu8tu2#

首先,您需要检索父窗口句柄,在Outlook中的Explorer窗口的情况下,您可以用途:

Outlook.Explorer explorer = OutlookApplication.ActiveExplorer();
IOleWindow oleWindow = explorer as IOleWindow;
IntPtr handle = IntPtr.Zero;

oleWindow.GetWindow(out handle);

if (handle != IntPtr.Zero)
{
    WindowInteropHelper helper = new WindowInteropHelper(DialogWindow);
    helper.Owner = handle;
    DialogWindow.ShowInTaskbar = false;
    DialogWindow.ShowDialog();
}

其中,IOleWindow可按以下方式定义:

/// <summary>
/// Implemented and used by containers and objects to obtain window handles
/// and manage context-sensitive help.
/// </summary>
/// <remarks>
/// The IOleWindow interface provides methods that allow an application to obtain
/// the handle to the various windows that participate in in-place activation,
/// and also to enter and exit context-sensitive help mode.
/// </remarks>
[ComImport]
[Guid("00000114-0000-0000-C000-000000000046")]
[InterfaceType (ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleWindow
{
    /// <summary>
    /// Returns the window handle to one of the windows participating in in-place activation
    /// (frame, document, parent, or in-place object window).
    /// </summary>
    /// <param name="phwnd">Pointer to where to return the window handle.</param>
    void GetWindow (out IntPtr phwnd) ;

    /// <summary>
    /// Determines whether context-sensitive help mode should be entered during an
    /// in-place activation session.
    /// </summary>
    /// <param name="fEnterMode"><c>true</c> if help mode should be entered;
    /// <c>false</c> if it should be exited.</param>
    void ContextSensitiveHelp ([In, MarshalAs(UnmanagedType.Bool)] bool fEnterMode) ;
}

相关问题