Как закрыть окно WPF без выключения. NET Приложение в IronPython - PullRequest
0 голосов
/ 15 февраля 2020

Итак, я пишу приложение WPF с Iron Python. Все отлично работает, если я запускаю скрипт вне Iron Python REPL с помощью команды "ipy.exe wpf.py". Однако, если сценарий был запущен внутри Iron Python REPL с помощью команды "execfile ('wpf.py')", при первом запуске OK, во втором при ошибке "SystemError: Невозможно создать более одной системы. Windows .Application экземпляр в том же AppDomain. "

Насколько я понимаю, это потому, что он будет создавать новый AppDomain каждый раз, когда вы запускаете его вне REPL, в то время как он будет использовать один и тот же домен при работе внутри REPL, и вы можете инициализировать Application дважды. Проблема в том, что мне приходится запускать его внутри одного и того же домена приложений много раз, поскольку это не отдельное приложение Iron Python. Я пробовал много вещей, таких как изменение режима выключения, добавив app.ShutdownMode = ShutdownMode.OnExplicitShutdown после app=Application(), но это просто повесило весь REPL.

Может кто-нибудь помочь пролить свет? Большое спасибо!

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 Ответ

1 голос
/ 15 февраля 2020

Я считаю, что вам нужно создать длительный поток STA для размещения приложения и обмениваться данными с ним через диспетчер приложений. Вот пример в 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();
            });

        }
    }
}
...