在Excel-DNA的.NET6类库中实现点击功能区按钮显示WPF控件及MVVM
解决Excel-DNA .NET6类库中显示WPF用户控件的方案
一、项目依赖配置
因为是.NET6类库,默认没有引用WPF相关框架,需要手动添加:
- 右键项目 → 添加 → 框架引用,勾选
PresentationCore、PresentationFramework、WindowsBase - 或者直接修改
.csproj文件,添加以下配置:
<ItemGroup> <FrameworkReference Include="Microsoft.WindowsDesktop.App.WPF" /> </ItemGroup>
二、核心代码实现
假设你的功能区按钮点击方法是PressMe,修改该方法以加载并显示WpfScreen.xaml:
1. WPF用户控件后台代码(WpfScreen.xaml.cs)
如果需要MVVM,直接在这里绑定ViewModel即可,和普通WPF项目一致:
using System.Windows.Controls; public partial class WpfScreen : UserControl { public WpfScreen() { InitializeComponent(); // MVVM场景下设置DataContext // DataContext = new WpfScreenViewModel(); } }
2. 功能区按钮点击逻辑
using System.Windows; using System.Windows.Threading; using ExcelDna.CustomUI; using ExcelDna.Integration; public class MyRibbon : ExcelRibbon { public void PressMe(IRibbonControl control) { // 初始化WPF应用环境(类库中无默认Application实例) if (Application.Current == null) { new Application(); // 全局异常捕获,避免崩溃影响Excel Application.Current.DispatcherUnhandledException += (s, e) => { ExcelIntegration.DisplayError(e.Exception, "WPF窗口错误"); e.Handled = true; }; } // 在WPF UI线程中创建并显示窗口 Application.Current.Dispatcher.Invoke(() => { // 创建承载用户控件的窗口 var hostWindow = new Window { Title = "自定义WPF界面", Width = 600, Height = 400, WindowStartupLocation = WindowStartupLocation.CenterOwner, // 设置窗口所有者为Excel主窗口,避免被遮挡 Owner = new System.Windows.Interop.WindowInteropHelper(hostWindow) { Owner = ExcelDnaUtil.WindowHandle }.Handle }; // 加载用户控件并设置为窗口内容 var wpfScreen = new WpfScreen(); hostWindow.Content = wpfScreen; // 模态显示窗口(如需非模态改用Show()) hostWindow.ShowDialog(); }); } }
三、关键注意事项
- 不要调用
Application.Run():Excel本身是运行中的进程,调用Run会阻塞Excel主线程 - 线程处理:必须在WPF的Dispatcher线程中操作UI元素,避免跨线程异常
- MVVM兼容性:和普通WPF项目完全一致,ViewModel实现
INotifyPropertyChanged即可正常绑定
内容的提问来源于stack exchange,提问作者user3641311
相关产品推荐
相关产品推荐

