如何在 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 应用程序的主要内容,如果未能解决你的问题,请参考以下文章