我从未创建过 Office 加载项,但我在其他类型的非 WPF 应用程序(Windows 窗体、从 WPF 视觉对象生成 .XPS 文件的库等)中使用了 WPF 窗口。您可以尝试我在这个问题中建议的方法。. 它展示了如何配置线程以便它能够运行 WPF 应用程序。如果您查看 WPF 应用程序的生成应用程序代码(“App.gics”),它似乎是这样开始的:
/// <summary>
/// Application Entry Point.
/// </summary>
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static void Main() {
WpfApplication1.App app = new WpfApplication1.App();
app.InitializeComponent();
app.Run();
}
我尝试使用以下代码从单元测试中启动一个应用程序,它运行良好:
[TestMethod]
public void TestMethod()
{
// The dispatcher thread
var t = new Thread(() =>
{
var app = new App();
// Corrects the error "System.IO.IOException: Assembly.GetEntryAssembly() returns null..."
App.ResourceAssembly = app.GetType().Assembly;
app.InitializeComponent();
app.Run();
});
// Configure the thread
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
}
编辑
查看您的代码,我相信对 SynchronizationContext 有意义的语句是创建 Window 实例,而不是创建您的 ViewModel(除非您的 ViewModel 处理 View 逻辑并实例化控件,否则它不应该这样做)。所以可以尝试将Window的实例化移动到App的线程中。像这样的东西:
[TestMethod]
public void TestMethod3()
{
// Creates the viewmodel with the necessary infomation wherever
// you need to.
MyViewModel viewModel = new MyViewModel(string infoFromOffice);
// The dispatcher thread
var t = new Thread(() =>
{
var app = new App();
// Corrects the error "System.IO.IOException: Assembly.GetEntryAssembly() returns null..."
App.ResourceAssembly = app.GetType().Assembly;
app.InitializeComponent();
// Creates the Window in the App's Thread and pass the information to it
MyWindow view = new MyWindow();
view.DataContext = viewModel;
app.Run(view);
});
// Configure the thread
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
}