C# WPF如何检测页面导航进入/离开状态控制逻辑执行
WPF导航场景下自动判断Startup页前台状态实现方案
核心思路是完全抛弃手动在按钮点击事件里更新标识的做法,通过监听导航服务的全局导航完成事件,自动识别当前前台展示的页面,零额外维护成本。
具体实现步骤
1. 定义全局运行状态存储
不要把状态标识写在页面类内部,单独建一个静态类存储全局状态,方便后台NFC线程无耦合访问:
public static class AppRuntimeState { /// <summary> /// 标识StartUp主页面是否处于前台显示状态 /// </summary> public static bool IsStartupPageActive { get; set; } }
2. 注册导航全局监听
在承载导航容器(一般是放置Frame控件的主窗口)的初始化逻辑中,给导航服务绑定Navigated事件,该事件会在导航彻底完成、新页面已渲染到前台时触发,比Navigating事件更适合做页面状态判定:
public MainWindow() { InitializeComponent(); // 仅需注册一次,全局生效 RootFrame.NavigationService.Navigated += NavigationService_OnNavigated; // 应用启动默认跳转至主页 RootFrame.Navigate(InstanceContainer.startup()); }
不推荐用
Navigating事件做状态判定的原因:该事件触发时导航尚未完成,还支持被取消,此时更新状态会导致标识和实际页面展示状态不一致,比如触发跳转但被拦截未跳走时,标识会被错误更新为非主页状态。
3. 自动更新状态标识
在导航完成的事件回调中,直接判断当前加载到前台的页面实例是否为Startup页,自动更新标识,所有跳转逻辑无需做任何额外修改:
private void NavigationService_OnNavigated(object sender, NavigationEventArgs e) { // 直接判断当前前台展示的内容是否为Startup页实例 // 因你使用InstanceContainer统一存储单例页面,此处类型判断100%准确 AppRuntimeState.IsStartupPageActive = e.Content is StartupPage; }
- 这套逻辑对所有跳转规则生效,不管是按钮点击跳转、程序自动触发跳转、还是系统导航回退/前进,都会自动更新状态,后续新增任何页面、新增任何跳转入口都不需要修改状态相关代码。
4. NFC扫描逻辑增加状态校验
后台NFC线程扫描到卡片时,直接读取全局状态判断是否执行业务即可:
private void OnNfcCardScanned(CardData data) { // 非主页前台状态下直接跳过业务执行 if (!AppRuntimeState.IsStartupPageActive) return; // 原有卡片处理业务逻辑 ProcessCardBusiness(data); }
可选线程安全优化
如果你的NFC回调运行在非UI线程,为了避免极端场景下的状态读写同步问题,可以把状态标识改成原子读写实现,不需要加锁,性能几乎无损耗:
public static class AppRuntimeState { private static int _startupActiveFlag = 0; public static bool IsStartupPageActive { get => Interlocked.CompareExchange(ref _startupActiveFlag, 0, 0) == 1; set => Interlocked.Exchange(ref _startupActiveFlag, value ? 1 : 0); } }
内容的提问来源于stack exchange,提问作者Jannes
相关产品推荐
相关产品推荐

