WPF自定义Page类型判断遇NullReferenceException异常求助
解决NullReferenceException及页面状态按钮问题
首先,你遇到的NullReferenceException直接原因是调用Main.Content.GetType()时,Main.Content为null,而核心问题出在按钮点击事件的逻辑顺序颠倒,以及PageState()方法里的判断错误:
问题拆解
- 逻辑顺序错误:按钮点击时你先调用
PageState()判断旧页面状态,再设置新页面内容,这会导致按钮状态和最终显示的页面不匹配,极端场景下还会触发空引用。 - 判断逻辑错误:
PageState()里的第二个条件写的是Main.GetType() == typeof(DataBasePage),但Main是Frame控件,它的类型永远是Frame,不可能匹配DataBasePage,这个判断永远不会生效。
具体修复步骤
1. 调整按钮点击事件的执行顺序
把设置页面内容的代码放在PageState()调用之前,让PageState()判断的是刚切换好的当前页面:
private void Menu_MonitorButton_Click(object sender, RoutedEventArgs e) { Main.Content = new MonitorPage(ref _watcher, ref _eventList); PageState(); } private void MenuStrip_DataBaseButton_Click(object sender, RoutedEventArgs e) { Main.Content = new DataBasePage(ref _eventList); PageState(); } private void MenuStrip_HelpButton_Click(object sender, RoutedEventArgs e) { Main.Content = new HelpPage(); PageState(); }
2. 修复PageState()的判断逻辑
用更安全的is运算符判断类型,同时添加按钮状态重置的辅助方法,避免重复代码:
private void PageState() { // 先重置所有按钮到默认状态 ResetButtonStates(); if (Main.Content is MonitorPage) { Menu_MonitorButton.IsEnabled = false; Menu_MonitorButton.Background = new SolidColorBrush(Color.FromRgb(88, 88, 95)); } else if (Main.Content is DataBasePage) { Menu_DataBaseButton.IsEnabled = false; Menu_DataBaseButton.Background = new SolidColorBrush(Color.FromRgb(88, 88, 95)); } else if (Main.Content is HelpPage) { Menu_HelpButton.IsEnabled = false; Menu_HelpButton.Background = new SolidColorBrush(Color.FromRgb(88, 88, 95)); } } // 辅助方法:重置按钮到初始状态 private void ResetButtonStates() { // 启用所有按钮 Menu_MonitorButton.IsEnabled = true; Menu_DataBaseButton.IsEnabled = true; Menu_HelpButton.IsEnabled = true; // 恢复默认背景色(和XAML中定义的一致) Menu_MonitorButton.Background = new SolidColorBrush(Color.FromRgb(78, 78, 83)); Menu_DataBaseButton.Background = new SolidColorBrush(Color.FromRgb(78, 78, 83)); Menu_HelpButton.Background = new SolidColorBrush(Color.FromRgb(78, 78, 83)); }
is运算符会自动处理Main.Content为null的情况,不会触发空引用异常,同时代码可读性更强。
3. 构造函数代码保持不变
构造函数里的顺序是正确的,先设置页面再调用状态判断,无需修改:
public MainWindow() { InitializeComponent(); Main.Content = new MonitorPage(ref _watcher, ref _eventList); PageState(); }
额外优化建议
- 可以把按钮的默认背景色定义为XAML资源(比如在
<Window.Resources>里),避免代码中硬编码颜色值,更易维护。 - 如果页面不需要每次都刷新数据,可以把三个页面实例缓存为类字段,点击时直接复用,提升程序性能。
内容的提问来源于stack exchange,提问作者Matthew Jett
相关产品推荐
相关产品推荐

