WinUI 3应用关闭时自动保存ViewModel状态?OnNavigatedFrom未触发
WinUI3 ViewModel状态保存解决方案
问题原因
INavigationAware接口的OnNavigatedFrom方法仅在页面间导航时触发,应用关闭(窗口关闭)属于应用生命周期事件,不会触发该导航方法,因此无法触发状态保存逻辑。
可行解决方案
1. 订阅窗口Closing事件
在主窗口代码后台监听Closing事件,手动调用ViewModel的状态保存方法,确保应用关闭前完成状态持久化:
步骤1:调整ViewModel的SaveStateAsync访问权限
将SaveStateAsync的访问修饰符改为public(直接调用更简洁),同时优化存储路径:
public async Task SaveStateAsync() { // 使用应用本地数据文件夹替代程序集目录,避免权限或临时目录问题 var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder.Path; var path = Path.Combine(localFolder, "main_view_model_state.json"); using FileStream fileStream = new(path, FileMode.Create); await JsonSerializer.SerializeAsync( fileStream, this, new JsonSerializerOptions { IgnoreReadOnlyProperties = true, }); }
步骤2:在MainWindow中绑定Closing事件
public sealed partial class MainWindow : Window { public MainViewModel ViewModel { get; } = new MainViewModel(); public MainWindow() { InitializeComponent(); Closing += MainWindow_Closing; } private async void MainWindow_Closing(object sender, WindowEventArgs e) { // 先阻止窗口关闭,等待状态保存完成 e.Cancel = true; await ViewModel.SaveStateAsync(); // 保存完成后手动关闭窗口 Close(); } }
2. 优化状态存储路径(必须调整)
原代码中Assembly.GetExecutingAssembly().Location获取的路径,在打包的WinUI3应用中属于临时安装目录,可能存在写入权限问题或被系统清理。改用应用本地数据文件夹是更可靠的选择,该路径专为应用持久化数据设计,不会被随意清理。
3. 应用级Exit事件(针对打包式WinUI3应用)
如果是打包发布的WinUI3桌面应用,还可以在App.xaml.cs中订阅OnExit事件:
protected override void OnExit(ExitEventArgs args) { // 获取ViewModel实例并触发保存 if (MainWindow.Content is Frame frame && frame.Content is MainPage mainPage) { _ = mainPage.ViewModel.SaveStateAsync(); } base.OnExit(args); }
注意:OnExit是同步方法,异步保存操作需确保能在应用退出前完成,避免长时间阻塞。
额外注意事项
- 避免在保存逻辑中执行耗时操作,防止应用关闭延迟;
- 可添加异常捕获,确保保存失败时不影响应用正常退出;
- 状态恢复逻辑保持原有实现即可,应用启动时
OnNavigatedTo能正常触发。
内容的提问来源于stack exchange,提问作者jack
相关产品推荐
相关产品推荐

