How to close WPF window without shutdown .NET Application in IronPython

回眸只為那壹抹淺笑 提交于 2020-02-23 07:11:10

问题


So I'm writing a WPF application with IronPython. Everything works great if I run the script outside of IronPython REPL via command "ipy.exe wpf.py". However, if the script were run inside IronPython REPL via command "execfile('wpf.py')", the first time it runs OK, the second time it errors out "SystemError: Cannot create more than one System.Windows.Application instance in the same AppDomain."

From my understanding, it's because it'll create a new AppDomain every time you run it outside REPL while it'll share the same domain when running inside REPL, and you can initialize Application twice. The problem is I have to run it inside the same AppDomain many times as it's not a standalone IronPython application. I've tried many things such as change shutdown mode by add app.ShutdownMode = ShutdownMode.OnExplicitShutdown after app=Application(), but that just hang the whole REPL.

Can someone please help shed some light? Thank you very much!

import clr
clr.AddReference("PresentationFramework")
clr.AddReference("PresentationCore")
clr.AddReference("System.Xml")

from System.Xml import XmlReader
from System.IO import StringReader
from System.Windows.Markup import XamlReader
from System.Windows import Application

s = XmlReader.Create(StringReader('''
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="IronPython MVVM Demo2"
    Width="450"
    SizeToContent="Height">
    <Grid Margin="15" x:Name="grid1">  
        <StackPanel Margin="5">
            <Button Margin="5">One</Button>
            <Button Margin="5">Two</Button>
            <Button Margin="5">Three</Button>
        </StackPanel>   
    </Grid>
</Window>
'''))

win = XamlReader.Load(s)

app = Application()     
app.Run(win)
print("The End.")   

回答1:


I believe you need to create a long-running STA thread to host the Applilcation, and communicate with it through the Applciations's Dispatcher. Here's an example in C#:

using System;
using System.IO;
using System.Threading;
using System.Windows;
using System.Xml;


namespace ConsoleApp1
{
    class Program
    {
        static void ShowWindow(string Xaml)
        {
            var s = XmlReader.Create(new StringReader(Xaml));
            var win = (Window)System.Windows.Markup.XamlReader.Load(s);
            win.ShowDialog();
        }
        static void Main(string[] args)
        {

           Application app = null;
           var UIThread = new Thread(() =>
           {
               app = new Application();
               app.ShutdownMode = ShutdownMode.OnExplicitShutdown;
               app.Run();
           });

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

            while (app == null )
                Thread.Sleep(100);

            app.Dispatcher.Invoke(() => Console.WriteLine("Started"));


            var xaml = @"
        <Window
            xmlns = ""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
            xmlns:x = ""http://schemas.microsoft.com/winfx/2006/xaml""
            Title = ""IronPython MVVM Demo2""
            Width = ""450""
            SizeToContent = ""Height"">
            <Grid Margin = ""15"" x:Name = ""grid1"">
                <StackPanel Margin = ""5"">
                    <Button Margin = ""5""> One </Button>
                    <Button Margin = ""5""> Two </Button>
                    <Button Margin = ""5""> Three </Button>
                </StackPanel>
            </Grid>
        </Window>";        

            for (int i = 0; i < 3; i++)
            {

                Application.Current.Dispatcher.Invoke(() =>
                {
                    ShowWindow(xaml);
                });
            }

            Application.Current.Dispatcher.Invoke(() =>
            {
                Application.Current.Shutdown();
            });

        }
    }
}


来源:https://stackoverflow.com/questions/60239880/how-to-close-wpf-window-without-shutdown-net-application-in-ironpython

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!