WPF窗口一闪而过,那你可能遇到空引用了
情况之一:ListBox中SelectionChanged与IsSelected引发的空引用
同时在ListBox使用了SelectionChanged属性,并且在其ListItem中使用了IsSelected属性。
而一旦这样做,那么在初始化函数InitializeComponent()执行的时候,IsSelected会使SelectionChanged事件被触发。
MainWinow.xaml
<Window x:Class="NullRefDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="空引用示例" Height="300" Width="400">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<!-- 左侧导航 -->
<ColumnDefinition Width="120"/>
<!-- 右侧内容 -->
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- ❗ 注意:ListBox 在 ContentControl 之前定义 -->
<ListBox x:Name="NavList" Grid.Column="0"
SelectionChanged="NavList_SelectionChanged">
<ListBoxItem IsSelected="True">首页</ListBoxItem>
<ListBoxItem>设置</ListBoxItem>
<ListBoxItem>关于</ListBoxItem>
</ListBox>
<!-- 内容区(x:Name="MainContent")定义在 ListBox 之后 -->
<ContentControl x:Name="MainContent" Grid.Column="1" />
</Grid>
</Window>
MainWindow.xaml.cs
using System.Windows;
using System.Windows.Controls;
namespace NullRefDemo
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void NavList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// ❌ 错误:这里的 MainContent 可能还是 null!
// 因为 InitializeComponent 先构造 ListBox,触发事件,
// 然后才会构造 ContentControl 并赋值给 MainContent 字段。
switch (NavList.SelectedIndex)
{
case 0:
MainContent.Content = new TextBlock { Text = "这是首页" };
break;
case 1:
MainContent.Content = new TextBlock { Text = "这是设置" };
break;
case 2:
MainContent.Content = new TextBlock { Text = "这是关于" };
break;
}
}
}
}
清注意!这时ListBox后面的标签还没有初始化,也就是说后面的x:Name=null。
这个例子是x:Name="MainContent",此时MainContent = null,如果这时SelectionChanged事件用到MainConten,就会触发空引用。
解决方法一:
private void NavList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// ✅ 如果 MainContent 还没初始化好,直接返回,等它好了再响应
if (MainContent == null) return;
switch (NavList.SelectedIndex)
{
// ... 同上的赋值逻辑
}
}
解决方法二:
删掉ListItem中的IsSelected属性,像下面这样写
public MainWindow()
{
InitializeComponent();
// 在 InitializeComponent 完成后再设选中项,此时所有控件均已就绪
NavList.SelectedIndex = 0;
}
我更建议使用方法二

浙公网安备 33010602011771号