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に適したステートメントは、ViewModelの作成ではなくWindowインスタンスの作成であると思います(ViewModelがViewロジックを処理し、コントロールをインスタンス化しない限り、実行すべきではありません)。したがって、ウィンドウのインスタンス化をアプリのスレッドに移動してみることができます。このようなもの:
[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();
}