wpfui 启动配置到优雅退出?WPF UI 生命周期各归谁管
2026/9/18 23:04:47 网站建设 项目流程

wpfui 启动配置到优雅退出?WPF UI 生命周期各归谁管

【免费下载链接】wpfuiWPF UI provides the Fluent experience in your known and loved WPF framework. Intuitive design, themes, navigation and new immersive controls. All natively and effortlessly.项目地址: https://gitcode.com/GitHub_Trending/wp/wpfui

关主窗口时任务栏图标残留一会儿才消失,启动时主窗口晚半拍才出现,原因几乎都是同一个:窗口、服务、宿主在抢 WPF UI 生命周期里的职责。下面用示例工程逐项核对 wpfui 启动配置的归属。

窗口创建之前:WPF 依赖注入注册如何喂给主窗口

OnStartup之前,容器已经建好:

private static readonly IHost _host = Host.CreateDefaultBuilder() .ConfigureServices((context, services) => { _ = services.AddHostedService<ApplicationHostService>(); _ = services.AddSingleton<IThemeService, ThemeService>(); _ = services.AddSingleton<ITaskBarService, TaskBarService>(); _ = services.AddSingleton<INavigationService, NavigationService>(); _ = services.AddSingleton<INavigationWindow, Views.MainWindow>(); }) .Build();

每一行都是“接口 → 实现”的映射:导航、主题、任务栏都挂在接口后面,主窗口自己也以INavigationWindow身份进了容器(见 App.xaml.cs)。容器实例化 MainWindow 时,视图模型和导航服务会直接交给它的构造函数,窗口自己不用new任何东西。

真正“造窗口”的是 ApplicationHostService。它是IHostedService,宿主调用StartAsync时接管窗口:

_navigationWindow = (serviceProvider.GetService(typeof(INavigationWindow)) as INavigationWindow)!; _navigationWindow!.ShowWindow(); _ = _navigationWindow.Navigate(typeof(Views.Pages.DashboardPage));

三行干三件事:从容器取出主窗口、显示它、落到位仪表盘页。宿主不关心窗口长什么样,窗口也不关心自己从哪来。

窗口活着时:导航、主题、任务栏进度条各归一个服务

窗口存续期间有三条动态线,各自有独立服务负责,窗口只干一件事:接线。

先是导航。MainWindow.xaml.cs 在构造时把窗口里的INavigationView交给导航服务:

public MainWindow(ViewModels.MainWindowViewModel viewModel, INavigationService navigationService) { ViewModel = viewModel; DataContext = this; Appearance.SystemThemeWatcher.Watch(this); InitializeComponent(); navigationService.SetNavigationControl(RootNavigation); }

SetNavigationControl把导航控件写进NavigationService,之后在视图模型里调Navigate(typeof(SettingsPage))就能换页,不用碰控件本身;Watch则让窗口跟随系统深浅色切换。

任务栏进度条 WPF:TaskBarService 按窗口存状态

有长耗时任务时,更新任务栏图标上的进度条:

taskBarService.SetValue(mainWindow, TaskBarProgressState.Normal, 50, 100);

TaskBarService.cs 内部按窗口句柄维护一份Dictionary<IntPtr, TaskBarProgressState>,每个窗口的进度状态各存各的,多窗口互不干扰,支持NormalErrorPaused等状态。

主题这条线则交给themeService.SetTheme(ApplicationTheme.Dark),由 ThemeService.cs 转发给ApplicationThemeManager.Apply,配合AppConfig即可把用户选择持久化。

WPF 优雅退出:停、放、存三步的顺序

退出表面是“窗口关了”,实际是一条链:窗口事件、应用关闭、宿主停止、容器释放,顺序不能乱。

MainWindowOnClosed先调Application.Current.Shutdown(),把关窗升格为退应用;App.xaml 的Exit事件接着触发OnExit

private async void OnExit(object sender, ExitEventArgs e) { await _host.StopAsync(); _host.Dispose(); }

StopAsync会依次执行各托管服务的StopAsync,持久化逻辑(比如把主题选择写进 JSON)就该放在这里;随后Dispose释放容器。顺序反了,服务停止时会访问已释放的 provider。

📋 防翻车自查清单:启动卡、泄漏、崩溃未捕获

以下四项是 wpfui 项目翻车的高发点,发布前逐条过一遍:

  • 启动卡:窗口构造函数里做同步读文件或长耗时网络调用。把耗时操作挪出构造函数,StartAsync里用Task.Run跑慢操作。
  • 内存泄漏:窗口订阅了静态事件或SystemThemeWatcher却没取消,确认每处Watch都有对应清理。
  • 崩溃未捕获:示例里的OnDispatcherUnhandledException是空实现,至少写日志并置e.Handled = true再弹提示。
  • 任务栏残留:退出前没SetState(window, TaskBarProgressState.None),图标上的进度条状态会一直在。

一句话收束:容器喂窗口、服务跑窗口、宿主收窗口。现在就能做三件事:通读 App.xaml.cs 记住注册顺序;跑一遍 samples/Wpf.Ui.Demo.Mvvm/ 示例工程;对照 src/Wpf.Ui/ 下的服务文件核对本文职责归属。

【免费下载链接】wpfuiWPF UI provides the Fluent experience in your known and loved WPF framework. Intuitive design, themes, navigation and new immersive controls. All natively and effortlessly.项目地址: https://gitcode.com/GitHub_Trending/wp/wpfui

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询