如何在 IronPython 中关闭 WPF 窗口而不关闭 .NET 应用程序

Posted

技术标签:

【中文标题】如何在 IronPython 中关闭 WPF 窗口而不关闭 .NET 应用程序【英文标题】:How to close WPF window without shutdown .NET Application in IronPython 【发布时间】:2020-02-15 14:49:11 【问题描述】:

所以我正在使用 IronPython 编写一个 WPF 应用程序。如果我通过命令“ipy.exe wpf.py”在 IronPython REPL 之外运行脚本,一切都会很好。但是,如果脚本是通过命令“execfile('wpf.py')”在 IronPython REPL 中运行的,第一次运行正常,第二次会出错“SystemError:无法创建多个 System.Windows.Application 实例在同一个 AppDomain 中。”

据我了解,这是因为每次在 REPL 外部运行时它都会创建一个新的 AppDomain,而在 REPL 内部运行时它会共享同一个域,并且您可以初始化 Application 两次。问题是我必须在同一个 AppDomain 中多次运行它,因为它不是独立的 IronPython 应用程序。我尝试了很多事情,例如通过在app=Application() 之后添加app.ShutdownMode = ShutdownMode.OnExplicitShutdown 来更改关机模式,但这只会挂起整个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】:

我相信您需要创建一个长时间运行的 STA 线程来托管 Applilcation,并通过 Applciations 的 Dispatcher 与其通信。这是 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();
            );

        
    

【讨论】:

谢谢大卫!我会尝试将其移植到 IronPython 并报告。

以上是关于如何在 IronPython 中关闭 WPF 窗口而不关闭 .NET 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

在 WPF Frame 控件中关闭导航页面声音

如何在WPF中关闭Tab关闭按钮?

WPF 中关闭窗口事件 我想在点"X"关闭时提示信息,如果选是则关闭程序如果轩否就不关闭

在 PyQt 中关闭窗口后如何检索属性值?

如何阻止用户在 Javascript 中关闭窗口?

如何检测在 $modal 中关闭模式窗口?角度-ui