.net Avalonia浏览器项目启动时出错:不知道如何检测Avalonia的应用退出事件,BrowserSingleViewLifetime

f0brbegy  于 2023-11-20  发布在  .NET
关注(0)|答案(1)|浏览(365)

community.我正在尝试使用官方文档中的下一个指南来实现数据持久化
https://docs.avaloniaui.net/docs/next/concepts/reactiveui/data-persistence
我尝试为浏览器和桌面实现状态持久化。If-else构造用于采用这些关键类型环境的不同MVVM实现。

public partial class App : Application
{
    public override void Initialize()
    {
        AvaloniaXamlLoader.Load(this);
    }

    public override void OnFrameworkInitializationCompleted()
    {
        IStateStorage<MainViewModel> stateStorage = ApplicationLifetime is IClassicDesktopStyleApplicationLifetime
            ? new LocalFileStateStorage<MainViewModel>("appstate.json")
            : new WebApiStateStorage<MainViewModel>("http://localhost:5173/ClientState");

        var suspensionDriver = new DefaultSuspensionDriver<MainViewModel>(stateStorage);

        var suspension = new AutoSuspendHelper(ApplicationLifetime);
        RxApp.SuspensionHost.CreateNewAppState = () => new MainViewModel();
        RxApp.SuspensionHost.SetupDefaultSuspendResume(suspensionDriver);
        suspension.OnFrameworkInitializationCompleted();

        // Load the saved view model state.
        var state = RxApp.SuspensionHost.GetAppState<MainViewModel>();

        if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
        {
            desktop.MainWindow = new MainWindow
            {
                DataContext = state
            };
            desktop.MainWindow.Show();
        }
        else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
        {
            singleViewPlatform.MainView = new MainView
            {
                DataContext = state
            };
        }

        base.OnFrameworkInitializationCompleted();
    }

字符串
但由于在浏览器中运行此代码,我得到了错误:
不知道如何检测Avalonia. BrowserSingleViewLifetime的应用退出事件。
有没有人知道如何修复它,使浏览器加载和保存ViewModel状态?

yks3o0rb

yks3o0rb1#

Avalonia社区帮助了我,并给了一个提示,当你关闭浏览器选项卡时-它“只是关闭”,没有事件和处理它的能力。在使用这些信息生活了一段时间后,我决定挖掘Avalonia源代码并找到AutoSuspendHelper构造函数的下一个代码:

public AutoSuspendHelper(IApplicationLifetime lifetime)
    {
        RxApp.SuspensionHost.IsResuming = Observable.Never<Unit>();
        RxApp.SuspensionHost.IsLaunchingNew = _isLaunchingNew;

        if (Avalonia.Controls.Design.IsDesignMode)
        {
            this.Log().Debug("Design mode detected. AutoSuspendHelper won't persist app state.");
            RxApp.SuspensionHost.ShouldPersistState = Observable.Never<IDisposable>();
        }
        else if (lifetime is IControlledApplicationLifetime controlled)
        {
            this.Log().Debug("Using IControlledApplicationLifetime events to handle app exit.");
            controlled.Exit += (sender, args) => OnControlledApplicationLifetimeExit();
            RxApp.SuspensionHost.ShouldPersistState = _shouldPersistState;
        }
        else if (lifetime != null)
        {
            var type = lifetime.GetType().FullName;
            var message = $"Don't know how to detect app exit event for {type}."; // Here exception throws!
            throw new NotSupportedException(message);
        }
        else
        {
            var message = "ApplicationLifetime is null. "
                        + "Ensure you are initializing AutoSuspendHelper "
                        + "after Avalonia application initialization is completed.";
            throw new ArgumentNullException(message);
        }
        
        var errored = new Subject<Unit>();
        AppDomain.CurrentDomain.UnhandledException += (o, e) => errored.OnNext(Unit.Default);
        RxApp.SuspensionHost.ShouldInvalidateState = errored;
    }

字符串
发现接口层次结构,我发现社区给出了绝对正确的提示,并决定重写我的App类,至少从我的WebApi服务器加载状态,并考虑将来实现一些手动状态保存:

public partial class App : Application
{
    public override void Initialize()
    {
        AvaloniaXamlLoader.Load(this);
    }

    public override void OnFrameworkInitializationCompleted()
    {
        IStateStorage<MainViewModel> stateStorage = ApplicationLifetime is IClassicDesktopStyleApplicationLifetime
            ? new LocalFileStateStorage<MainViewModel>("appstate.json")
            : new WebApiStateStorage<MainViewModel>("http://localhost:5173/ClientState");

        if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
        {
            // now this code 
            var suspensionDriver = new DefaultSuspensionDriver<MainViewModel>(stateStorage);

            var suspension = new AutoSuspendHelper(ApplicationLifetime);
            RxApp.SuspensionHost.CreateNewAppState = () => new MainViewModel();
            RxApp.SuspensionHost.SetupDefaultSuspendResume(suspensionDriver);
            suspension.OnFrameworkInitializationCompleted();

            // Load the saved view model state.
            var state = RxApp.SuspensionHost.GetAppState<MainViewModel>();

            desktop.MainWindow = new MainWindow
            {
                DataContext = state
            };
            desktop.MainWindow.Show();
        }
        else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
        {
            var state = stateStorage.Load();

            singleViewPlatform.MainView = new MainView
            {
                DataContext = state
            };
        }

        base.OnFrameworkInitializationCompleted();
    }
}


结论我做的是更好的Ctrl+点击的方法与异常,而不是立即尝试谷歌它(对于这样年轻的框架有非常小的知识库)。

相关问题