Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation for shutting down manually (via lifetimes) #59

Open
ewrogers opened this issue Apr 22, 2023 · 0 comments
Open

Add documentation for shutting down manually (via lifetimes) #59

ewrogers opened this issue Apr 22, 2023 · 0 comments
Labels
content request New docs requires

Comments

@ewrogers
Copy link

ewrogers commented Apr 22, 2023

Coming from WPF's App.Current.Shutdown() it is not immediately obvious what the analog is for Avalonia. After reading about Lifetimes, it makes sense why things are not as simple as WPF but still left me wondering "okay, so how do I quit the desktop app?"

Going the classic MVVM route I was essentially trying to map a "Quit" MenuItem to shutdown the application and do any user prompting ceremony.

The first step was learning that the IClassicDesktopStyleApplicationLifetime interface (try saying that 5 times fast) is where the expected Shutdown() (or TryShutdown()) method lives. But how would I access this from my MainWindowViewModel?

The solution I came up with was to inject that lifetime into the VM and rework the startup code a bit:

App.axaml.cs:

public override void OnFrameworkInitializationCompleted()
{
    if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
    {
        desktop.MainWindow = new MainWindow { DataContext = new MainWindowViewModel(desktop) };
        // Kinda gross, maybe pass (exitCode) => desktop.Shutdown(exitCode) instead?
    }

    base.OnFrameworkInitializationCompleted();
}

MainWindowViewModel.cs:

public sealed class MainWindowViewModel : ReactiveObject
{
    // Maybe store an Action<int> requestQuit instead?
    private readonly IClassicDesktopStyleApplicationLifetime _lifetime;
    
    private string _windowTitle = App.AppName;

    public string WindowTitle
    {
        get => _windowTitle;
        set => this.RaiseAndSetIfChanged(ref _windowTitle, value);
    }

    public MainWindowViewModel(IClassicDesktopStyleApplicationLifetime lifetime)
    {
        _lifetime = lifetime;
    }

    public void OnQuitRequested() => _lifetime.Shutdown();
}

MainWindow.axaml:

...
<MenuItem Header="_Quit" HotKey="Ctrl+Q" Command="{ReflectionBinding OnQuitRequested}"/>
...

This works great and "feels" the most clean approach. I didn't love needing the entire lifetime interface stored by the VM, so maybe passing an Action<int> requestQuit that calls lifetime.Shutdown(exitCode) instead could be more de-coupled approach.

Anyways, it would be nice if something like this could be documented as it seems fairly elementary in the context of desktop applications.

@maxkatz6 maxkatz6 added the content request New docs requires label Apr 22, 2023
@grokys grokys mentioned this issue Jun 22, 2023
31 tasks
@maxkatz6 maxkatz6 transferred this issue from another repository Jun 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
content request New docs requires
Projects
None yet
Development

No branches or pull requests

2 participants