Запуск WPF-окон из Office добавить в

Я создал служебную надстройку, которая содержит экземпляр приложения WPF. Когда пользователь нажимает кнопки надстройки, я запускаю разные окна, выполняя следующие действия:

MyViewModel viewModel = new MyViewModel(string infoFromOffice);
MyWindow view = new MyWindow();
view.DataContext = viewModel;

wpfApp.Run(view);

При построении вида моделей перед моим звонкомwpfApp.Run() Я попал в проблему с текущим SynchronizationContext позже. ОтветВот объясняет почему Есть ли лучший способ запуска Windows WPF из офисной надстройки?

 Coder109516 нояб. 2012 г., 17:57
Спасибо за предложение, к сожалению, это не работает.
 Jay16 нояб. 2012 г., 17:20
Из любопытства, имеет ли смысл звонитьwpfApp.Run(new MyWindow { DataContext = new MyViewModel(infoFromOffice) });

Ответы на вопрос(3)

но я использовал окна WPF в других видах приложений, не относящихся к WPF (Windows Forms, библиотеки для создания файлов .XPS из визуальных элементов WPF и т. д.). Вы можете попробовать подход, который я предложил вэтот вопрос., В нем показано, как настроить поток, чтобы он мог запускать приложение WPF. Если вы посмотрите на сгенерированное приложениекод ("App.g.i.cs») из приложения WPF, кажется, оно запускается так:

/// <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 и не создает экземпляры элементов управления, чего не следует делать)т делать). Таким образом, вы можете попытаться перенести создание экземпляра окна в поток приложения. Что-то вроде этого:

[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();
    }
 Arthur Nunes19 нояб. 2012 г., 16:04
Я полагаю, что проблема с интенсификацией Окна. Смотрите отредактированный ответ. "
 Coder109519 нояб. 2012 г., 10:57
Спасибо, это полезный пример, но нене решить проблему. Здесь модели представлений создаются после вызова app.Run (). Поскольку мне нужно передать своей модели представления некоторую информацию, ее необходимо создать перед вызовом app.Run (). Это означает, что во время построения модели представления нет диспетчера, что вызывает проблемы, а именно с получением SynchronizationContext.Current.
 Coder109520 нояб. 2012 г., 10:22
если ваша ViewModel не работает с логикой View и не создает экземпляры элементов управления, то это не должноне делать ", Я думаю, что это ключ здесь. Моя программа использует фоновые потоки (задачи) для запроса базы данных, а затем обновляет пользовательский интерфейс через поток пользовательского интерфейса. Если я использую одну из этих задач в конструкторе модели представления (перед вызовом app.Run ()), она завершится неудачно, поскольку SynchronizationContext.Current имеет значение null. Я полагаю, исправление состоит в том, чтобы просто не выполнять запрос к базе данных в конструкторе модели представления. Спасибо, что помогли мне с этим.

использующая домен приложения для многократного открытия приложения wpf в отдельных доменах приложения и потоке пользовательского интерфейса. Использовал это в служебной надстройке. Каждый раз при запуске вы получаете новое приложение. Не проверили, насколько хорошо закрываются потоки при закрытии приложения wpf.

http://eprystupa.wordpress.com/2008/07/31/running-multiple-wpf-applications-in-the-same-process-using-appdomains/

открытый класс WpfHelper {}

   public static void Startup()
    {
        var appDomainSetup = new AppDomainSetup()
        {
            ApplicationBase = Path.GetDirectoryName(typeof(WpfHelper).GetType().Assembly.Location)
        };

        AppDomain domain = AppDomain.CreateDomain(DateTime.Now.ToString(), null, appDomainSetup);

        CrossAppDomainDelegate action = () =>
        {
            Thread thread = new Thread(() =>
            {
                var app = new WpfApplication.App();

                WpfApplication.App.ResourceAssembly = app.GetType().Assembly;

                app.MainWindow = new WpfApplication.MainWindow();
                app.MainWindow.Show();
                app.Run();
            });

            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();

        };

        domain.DoCallBack(action);
    }

Решение Вопроса

но на самом деле не ответил, как передавать данные в модель представления из хост-приложения, в то время как вызов конструктора модели представления оставался после вызоваApp.Run(), С тех пор я нашел (очень простое) решение! Для тех, кто заинтересован.

В App.xaml.cs:

private string data;

public App(string infoFromOffice) {
    this.data = data;
}

protected override void OnStartup(StartupEventArgs e) {
    base.OnStartup(e);

    MyViewModel viewwModel = new MyViewModel(this.data);
    MyWindow view = new MyWindow();
    view.Show();
}

При запуске приложения:

App application = new App(infoFromOffice);
application.Run();

Обратите внимание, что URI запуска необходимо удалить в App.xaml. Это очень простое решение позволяет мне передавать информацию в мое приложение, но в то же время не требует, чтобы модель представления была построена в виде "не WPF среда " и так может использовать Диспетчер и т. д.

Ваш ответ на вопрос