从Office启动WPF窗口中添加(Launching WPF windows from an Of

2019-07-03 21:54发布

我已经创建了一个Office加载保存WPF应用程序的一个实例。 当用户点击加载按钮,我启动通过执行以下不同的窗口:

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

wpfApp.Run(view);

在我的电话之前构建视图模型wpfApp.Run()我打与当前的SynchronizationContext以后probelms。 答案在这里解释了为什么。 有没有从Office加载推出WPF窗口的更好的办法?

Answer 1:

我从来没有创建的Office加载,但我已经使用其他种类的非WPF应用程序WPF窗口(Windows窗体,库生成WPF的视觉效果,等.XPS文件)。 你可以尝试我建议的方法这个问题。 。 它显示了如何配置一个线程,这样它就能运行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的语句是窗口实例的创建,而不是创造你的视图模型的(除非查看逻辑视图模型的交易和实例的控制,这事不应该做)。 所以,你可以尝试将窗口的实例移动到应用程序的线程。 事情是这样的:

[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();
    }


Answer 2:

虽然亚瑟的回答帮点为什么这个问题是怎么回事,它实际上并没有回答,同时还具有视图模型构造函数调用被调用后,如何将数据从一个主机应用程序传递给视图模型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环境”构建等都可以利用调度等。



Answer 3:

下面是一个使用应用程序域多次打开WPF应用程序下单独的应用程序域和UI线程版本。 在办公室的插件用这个。 每次启动时叫你得到一个新的应用程序。 没有验证如何线程关闭时,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);
    }

}



文章来源: Launching WPF windows from an Office add in