我编写了一个WordAddIn,允许用户调用当前文档的某些元数据。通过功能区中的自定义按钮,他们可以调用WPF。 WPF调用实现如下:
System.Windows.Application app = null;
然后在按钮调用的方法中:
if (app == null)
{
app = new System.Windows.Application { ShutdownMode = ShutdownMode.OnExplicitShutdown };
app.Run();
}
MainWindow win = new MainWindow(graph);
app.Dispatcher.Invoke((Action)(() => { win.Show(); }));
Word启动后第一次单击该按钮时,没有任何反应,也无法编辑word文档中的内容。第二次单击该按钮时,WPF对象会加载并显示,这也适用于之后的任何按钮单击。因此,似乎第一次调度调度程序,它就会挂起。我该如何防止这种情况?
答案 0 :(得分:2)
我不知道你为什么要分派这个电话,因为这是同一个线程。当“当前”线程不是UI线程时,您只需要对UI线程进行编组操作,这不是您的情况 - 您只有一个线程。
其次,Application.Run是一种阻塞方法,不应在加载项上下文中调用。您无法在加载项应用程序中创建WPF应用程序。顺便说一句,Application.Run总是在当前线程上运行,在你的情况下,运行相同的一个Word加载项。这应该如何。
如果我理解正确,那么您正在创建一个WPF应用程序,因为您不想使用WinForms技术而是使用WPF。如果没有Application.Run,请不要调度,因为没有理由这样做。
答案 1 :(得分:0)
我在Microsoft WPF论坛中得到了这方面的帮助。在新线程中创建和调用app可以解决这个问题,因为app确实阻止了它被调用的当前线程。
if (app == null)
{
Thread thread = new Thread(new ThreadStart(() =>
{
app = new System.Windows.Application { ShutdownMode = ShutdownMode.OnExplicitShutdown };
autoResetEvent.Set();
app.Run();
}));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
else
{
autoResetEvent.Set();
}
autoResetEvent.WaitOne(); //wait until app has been initialized on the other thread
app.Dispatcher.Invoke((Action)(() => { new MainWindow(graph).Show(); }));
}