简体   繁体   中英

How can I pass application control to another WPF window?

I'm setting up a simple WPF application, which looks at its command-line arguments to determine what kind of window should be shown next. When that's determined, I show the next window by calling new ApplicationWindow() , set the content, and call Show() . The problem is that the MainWindow instance seems to have "application control" - ie when it closes, so does everything else.

It goes like this:

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();
    }
}

These methods get called in the order I've put them here, through various events. I've omitted a few fields and properties.

The problem is that when this MainWindow closes, so does window - the instantiated ApplicationWindow . I assume this is because the MainWindow created it.

However, I do want to be able to close the MainWindow and continue with another window as the "main" window - so how can I decouple the instantiated ApplicationWindow from its parent MainWindow so it continues on?

I've seen setting Application.MainWindow in App.xaml changes the main window - but I have no reference to the instantiated window that I can put into a static XAML file.

Why are you parsing the command line args in your MainWindow?

You could just remove the StartupUri in the App.xaml and override the OnStartup method. Then you can use StartUpArgs to decide which operating mode you want.

In 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);
}

What I think you could do (now there are better options I'm sure...) is instead of creating a new window in your main program, move your other code into a new project and in your main project, launch it as a new process with Process.Start(...) . I've only ever seen code that used this though, never written it from scratch myself. But I would take a look at this page from the MDSN and pages related to it.
Excuse the lack of example code to help you, this is just at the edge of my knowledge and I'd hate to give you incorrect code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM