首页 > 解决方案 > WPF、Excel 和 ContextMenu

问题描述

我实现了一个简单的 WPF-Window 以加载到 Excel 的 VSTO-Addin 应用程序中。

上下文菜单闪烁,即它被显示并突然消失;这只发生在窗口不是模态的时候。

重现问题非常简单;首先,您必须创建一个 Excel 200X VSTO 插件。

添加一个 WPF 用户控件,将根节点从 UserControl 更改为 Window。一致地更改后面的代码,即将超类从 UserControl 替换为 Window。

这是创建 WPF 窗口的技巧,因为当您使用 VSTO 外接程序时,项目项之间没有 WPF 窗口。这也是问题最有可能的罪魁祸首。
该窗口仅包含一个带有上下文菜单的标签。

xml:

<Window x:Class="ExcelAddIn9.MyWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:ExcelAddIn9"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
<StackPanel>
    <Label>Some label
        <Label.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Context Menu"/>
            </ContextMenu>
        </Label.ContextMenu>
    
    </Label>
</StackPanel>
</Window>

当它工作时,输出是愚蠢的:

工作上下文菜单

只是为了展示,您可以从 ThisAddIn 类中的任何位置打开窗口。

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        MyWindow w = new MyWindow();
        w.Show();

    }

这闪烁。让它工作更改w.Show()w.ShowDialog(). 同样,这不是您在实际应用程序中放置对话框的地方,因为它会阻止 excel 加载,但为了显示问题,它是可以的。

正如我所说,我认为这可能是他们不为 VSTO 项目提供 WPF-Window 项目的原因之一,但同样我想深入调查这个问题以便让 ContextMenu 也能工作在非对话应用程序中。
而且我想检查这个问题是否是 VSTO 中 WPF 窗口基本故障的症状并评估其他解决方案(可能将它们嵌入到 WinForms 窗口中)。

VSTO 版本 2010。

标签: c#excelwpfvsto

解决方案


您必须指定父 Outlook 窗口句柄 ( Owner)。使用有助于 Windows Presentation Foundation (WPF) 和 Win32 代码之间的互操作的WindowInteropHelper类。

一个示例场景是,如果您需要在 Win32 应用程序中托管 WPF 对话框。使用对话框的 WPF 窗口对象初始化 WindowInteropHelper。然后,您可以从 Handle 属性获取 WPF 窗口的句柄 (HWND),并使用 Owner 属性指定 WPF 窗口的所有者。以下代码示例显示了在 Win32 应用程序中承载 WPF 对话框时如何使用 WindowInteropHelper。

WindowInteropHelper wih = new WindowInteropHelper(myDialog);
wih.Owner = ownerHwnd;
myDialog.Show();

推荐阅读