如何将应用程序控制传递给另一个 WPF window?
How can I pass application control to another WPF window?
我正在设置一个简单的 WPF 应用程序,它会查看其命令行参数以确定接下来应显示哪种 window。确定后,我通过调用 new ApplicationWindow()
显示下一个 window,设置内容,然后调用 Show()
。问题是 MainWindow
实例似乎有 "application control" - 即当它关闭时,其他所有内容也会关闭。
它是这样的:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TopBar.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF1975DD"));
this.ContentRendered += MainWindow_ContentRendered;
this.OperationModeSet += MainWindow_OperationModeSet;
}
[STAThread]
private void MainWindow_ContentRendered(object sender, EventArgs e)
{
Thread worker = new Thread(new ThreadStart(this.ParseCommandLineArgs));
worker.SetApartmentState(ApartmentState.STA);
worker.Start();
}
[STAThread]
public void ParseCommandLineArgs()
{
Thread.Sleep(3000);
string[] args = Environment.GetCommandLineArgs();
if (args.Any(item => item == "--server" || item == "-s"))
{
SetOperationMode(OperationMode.Server);
Dispatcher.BeginInvoke(new Action(delegate()
{
this.CloseWindow();
}));
}
else
{
SetOperationMode(OperationMode.Client);
Dispatcher.BeginInvoke(new Action(delegate()
{
this.CloseWindow();
}));
}
}
[STAThread]
private void SetOperationMode(OperationMode mode)
{
OperatingMode = mode;
if (OperationModeSet != null)
{
OperationModeSet(this, new OperationModeSetEventArgs(mode));
}
}
[STAThread]
private void MainWindow_OperationModeSet(object sender, OperationModeSetEventArgs e)
{
AppWindow window = new AppWindow();
if (e.Mode == OperationMode.Client)
{
this.CloseWindow();
window.Content = new ClientPage();
}
else if (e.Mode == OperationMode.Server)
{
this.CloseWindow();
window.Content = new ServerPage();
}
window.Show();
}
}
这些方法是按照我在此处放置它们的顺序通过各种事件调用的。我省略了一些字段和属性。
问题是当 this MainWindow
关闭时,window
- 实例化的 ApplicationWindow
也会关闭。我认为这是因为 MainWindow
创建了它。
但是,我确实希望能够关闭 MainWindow
并继续使用另一个 window 作为 "main" window - 那么我如何解耦实例化的ApplicationWindow
来自其父级 MainWindow
所以它会继续吗?
我看到 App.xaml 中的设置 Application.MainWindow 改变了主 window - 但我没有引用实例化的 window 可以放入静态XAML 文件。
我认为您可以做的(我相信现在有更好的选择...)不是在您的主程序中创建一个新的 window,而是将您的其他代码移动到一个新项目中,然后在您的主项目中,使用 Process.Start(...)
将其作为新进程启动。
不过,我只见过使用它的代码,我自己从未从头开始编写过。但我会看一下 this page from the MDSN 和与之相关的页面。
请原谅缺少示例代码来帮助您,这只是我知识的边缘,我不想给您不正确的代码。
为什么要在 MainWindow 中解析命令行参数?
您可以只删除 App.xaml 中的 StartupUri 并覆盖 OnStartup 方法。然后你可以使用StartUpArgs来决定你想要的操作模式。
在App.xaml.cs
protected override void OnStartup(StartupEventArgs e)
{
// Decide which window to show here
// Add bounds checks etc.
if (e.Args[0] == "-s")
{
var window = new ServerPage();
window.Show();
}
else
{
var window = new ClientPage();
window.Show();
}
Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
base.OnStartup(e);
}
我正在设置一个简单的 WPF 应用程序,它会查看其命令行参数以确定接下来应显示哪种 window。确定后,我通过调用 new ApplicationWindow()
显示下一个 window,设置内容,然后调用 Show()
。问题是 MainWindow
实例似乎有 "application control" - 即当它关闭时,其他所有内容也会关闭。
它是这样的:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TopBar.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF1975DD"));
this.ContentRendered += MainWindow_ContentRendered;
this.OperationModeSet += MainWindow_OperationModeSet;
}
[STAThread]
private void MainWindow_ContentRendered(object sender, EventArgs e)
{
Thread worker = new Thread(new ThreadStart(this.ParseCommandLineArgs));
worker.SetApartmentState(ApartmentState.STA);
worker.Start();
}
[STAThread]
public void ParseCommandLineArgs()
{
Thread.Sleep(3000);
string[] args = Environment.GetCommandLineArgs();
if (args.Any(item => item == "--server" || item == "-s"))
{
SetOperationMode(OperationMode.Server);
Dispatcher.BeginInvoke(new Action(delegate()
{
this.CloseWindow();
}));
}
else
{
SetOperationMode(OperationMode.Client);
Dispatcher.BeginInvoke(new Action(delegate()
{
this.CloseWindow();
}));
}
}
[STAThread]
private void SetOperationMode(OperationMode mode)
{
OperatingMode = mode;
if (OperationModeSet != null)
{
OperationModeSet(this, new OperationModeSetEventArgs(mode));
}
}
[STAThread]
private void MainWindow_OperationModeSet(object sender, OperationModeSetEventArgs e)
{
AppWindow window = new AppWindow();
if (e.Mode == OperationMode.Client)
{
this.CloseWindow();
window.Content = new ClientPage();
}
else if (e.Mode == OperationMode.Server)
{
this.CloseWindow();
window.Content = new ServerPage();
}
window.Show();
}
}
这些方法是按照我在此处放置它们的顺序通过各种事件调用的。我省略了一些字段和属性。
问题是当 this MainWindow
关闭时,window
- 实例化的 ApplicationWindow
也会关闭。我认为这是因为 MainWindow
创建了它。
但是,我确实希望能够关闭 MainWindow
并继续使用另一个 window 作为 "main" window - 那么我如何解耦实例化的ApplicationWindow
来自其父级 MainWindow
所以它会继续吗?
我看到 App.xaml 中的设置 Application.MainWindow 改变了主 window - 但我没有引用实例化的 window 可以放入静态XAML 文件。
我认为您可以做的(我相信现在有更好的选择...)不是在您的主程序中创建一个新的 window,而是将您的其他代码移动到一个新项目中,然后在您的主项目中,使用 Process.Start(...)
将其作为新进程启动。
不过,我只见过使用它的代码,我自己从未从头开始编写过。但我会看一下 this page from the MDSN 和与之相关的页面。
请原谅缺少示例代码来帮助您,这只是我知识的边缘,我不想给您不正确的代码。
为什么要在 MainWindow 中解析命令行参数?
您可以只删除 App.xaml 中的 StartupUri 并覆盖 OnStartup 方法。然后你可以使用StartUpArgs来决定你想要的操作模式。
在App.xaml.cs
protected override void OnStartup(StartupEventArgs e)
{
// Decide which window to show here
// Add bounds checks etc.
if (e.Args[0] == "-s")
{
var window = new ServerPage();
window.Show();
}
else
{
var window = new ClientPage();
window.Show();
}
Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
base.OnStartup(e);
}