Non ho mai creato un componente aggiuntivo di Office, ma ho utilizzato Windows WPF in altri tipi di applicazioni non WPF (Windows Form, librerie per generare file .XPS da visual WPF, ecc.). Puoi provare l'approccio suggerito in this question.. Mostra come configurare un thread in modo che sia in grado di eseguire l'app WPF. Se si dà un'occhiata sul codice dell'app generato ("App.gics") di un'applicazione WPF, a quanto pare è iniziato in questo modo:
/// <summary>
/// Application Entry Point.
/// </summary>
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static void Main() {
WpfApplication1.App app = new WpfApplication1.App();
app.InitializeComponent();
app.Run();
}
Ho provato a lanciare un app da un test di unità con il codice seguente e ha funzionato bene:
[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();
}
EDIT
Guardando il codice credo che la dichiarazione sensibile al SynchronizationContext è la creazione dell'istanza finestra, non la creazione del tuo ViewModel (a meno che ViewModel non abbia a che fare con la logica View e i controlli di istanza, qualcosa che non dovrebbe fare). Quindi puoi provare a spostare l'istanza della finestra sul thread dell'app. Qualcosa di simile a questo:
[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();
}
fonte
2012-11-16 18:04:59
Per curiosità, ci si fa alcuna differenza per chiamare 'wpfApp.Esegui (new MyWindow {DataContext = new MyViewModel (infoFromOffice)}); ' – Jay
Grazie per il suggerimento, sfortunatamente questo non funziona. – Coder1095