在Office应用中打开WPF窗体并且让子窗体显示在Office应用上

在.NET主程序中,我们可以通过创建 ExcelApplication 对象来打开一个Excel应用程序,如果我们想在Excle里面再打开WPF窗口,问题就不那么简单了。

我们可以简单的实例化一个WPF窗体对象然后在Office应用程序的窗体上打开这个新的WPF窗体,此时Office应用的窗体就是WPF的宿主窗体。然后宿主窗体跟Office应用并不是在一个UI线程上,子窗体很可能会在宿主窗体后面看不到。这个时候需要调用Win32函数,将Office应用的窗体设置为WPF子窗体的父窗体,这个函数的形式定义如下:

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

由于Office应用程序是非托管程序,WPF窗体是托管程序,.NET提供了一个 WindowInteropHelper 包装类,它可以将一个托管程序窗体包装得到一个窗口句柄,之后,就可以调用上面的Win32函数 SetParent 设置窗口的父子关系了。

下面方法是一个完整的方法,可以通过反射实例化一个WPF窗体对象,然后设置此WPF窗体对象为Office应用程序的子窗体,并正常显示在Office应用程序上。

   /// <summary>
        /// 在Excle窗口上显示WPF窗体
        /// </summary>
        /// <param name="assemplyName">窗体对象所在程序集</param>
        /// <param name="paramClassFullName">窗体对象全名称</param>
        public static void ExcelShowWPFWindow(string assemplyName, string paramClassFullName)
        {
            Application.Current.Dispatcher.Invoke(new Action(() => {
                try
                {
                    Assembly assembly = Assembly.Load(assemplyName);
                    Type classType = assembly.GetType(paramClassFullName);
                    object[] constuctParms = new object[] { };
                    dynamic view = Activator.CreateInstance(classType, constuctParms);
                    Window winBox = view as Window;
                    var winBoxIntreop = new WindowInteropHelper(winBox);
                    winBoxIntreop.EnsureHandle();
                    //将Excel句柄指定为当前窗体的父窗体的句柄,参考 https://blog.csdn.net/pengcwl/article/details/7817111
                    //ExcelApp 是一个Excle应用程序对象
                    var excelHwnd = new IntPtr(OfficeApp.ExcelApp.Hwnd);
                    winBoxIntreop.Owner = excelHwnd;
                    SetParent(winBoxIntreop.Handle, excelHwnd);
                    winBox.ShowDialog();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("打开窗口错误:"+ex.Message);
                }
            }));
        }
    }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

.NET Framework 4.5.2 静默安装参数

Microsoft .NET Framework 4.5.2 是针对 Microsoft .NET Framework 4、Microsoft .NET Fra...

35180
来自专栏张善友的专栏

MONO x64 amd_x64

SharpPcap 是一个.NET 环境下的网络包捕获框架,基于著名的 pcap/WinPcap 库开发。提供了捕获、注入、分析和构建的功能,SharpPcap...

20650
来自专栏林德熙的博客

Visual studio 创建项目失败vstemplate

Visual studio 创建项目失败 提示 the vstemplate file references the wizard class ‘Microso...

14610
来自专栏张善友的专栏

使用Autofac在ASP.NET Web API上实现依赖注入

【原文】 Dependency Injection with ASP.NET Web API and Autofac,以下为摘要: 在ASP.NET Web A...

29490
来自专栏陈仁松博客

【译】在 ASP.NET Core 中使用 SignalR

近日,微软发布了.NET Core 2.0,但是开发人员中间仍然存在一些疑惑,就是.NET Core、.NET Standard、Xamarin和.NET Fr...

41940
来自专栏醉梦轩

在Windows上编译openssl

18030
来自专栏.NET开发者社区

(码友推荐)2018-10-19 .NET及相关开发资讯速递

3.Using an OData Client with an ASP.NET Core API

11030
来自专栏张善友的专栏

LINQPad

类似于Sql Management studio一个用于Linq语法的工具LINQPad。 LINQPad lets you interactively qu...

25090
来自专栏张善友的专栏

asp.net mvc本地程序集和GAC的程序集冲突解决方法

一个从asp.net mvc 3升级到asp.net mvc 4的项目发生了如下错误: [A]System.Web.WebPages.Razor.Config...

23350
来自专栏施炯的IoT开发专栏

Windows Phone SDK 7.1 RTM 发布

自昨天开始发规模推送Mango,今天又看到Windows Phone SDK 7.1 RTM可以下载了,大家可以去Microsoft Download Cen...

20060

扫码关注云+社区

领取腾讯云代金券