如何让WPF ListBox失去焦点后仍保持选中项高亮?
解决ListBoxItem在焦点移到外部TextBox后丢失高亮的问题
我明白你的问题了:当焦点在ListBox内部的TextBox时,对应的ListBoxItem会高亮,但一旦焦点移到外部的theTextBox,这个高亮就消失了。这是因为你原来用的IsKeyboardFocusWithin触发器只有当焦点处于ListBoxItem的范围内时才会生效,焦点移出去后这个属性就变成False了。下面给你一个简单有效的解决方案:
核心思路
我们可以利用ListBox的SelectedItem来跟踪“活动”的项:当内部TextBox获得焦点时,把对应的Item设为ListBox的SelectedItem,然后让ListBoxItem在IsSelected状态下保持高亮。这样即使焦点移到外部TextBox,只要SelectedItem没改变,高亮就会保留。
修改后的完整代码
XAML部分
<DockPanel> <ListBox x:Name="itemListBox" ItemsSource="{Binding Items}" DockPanel.Dock="Top" Height="100" KeyboardNavigation.TabNavigation="Cycle"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Setter Property="IsTabStop" Value="False"/> <Setter Property="Focusable" Value="False"/> <!-- 默认样式 --> <Setter Property="Background" Value="Transparent"/> <Style.Triggers> <!-- 当Item被选中时保持高亮 --> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background" Value="LightGreen" /> </Trigger> <!-- 联动焦点与选中状态:焦点在内部时自动选中 --> <Trigger Property="IsKeyboardFocusWithin" Value="True"> <Setter Property="IsSelected" Value="True"/> </Trigger> </Style.Triggers> </Style> </ListBox.ItemContainerStyle> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Vertical"> <TextBlock Text="{Binding Name}"/> <TextBox Text="{Binding Description}" GotKeyboardFocus="TextBox_GotKeyboardFocus"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <!-- 修正了Name属性的语法错误:把-改成= --> <TextBox Name="theTextBox" AcceptsReturn="True" /> </DockPanel>
C#后台代码
在你的窗口/UserControl的代码文件中添加以下事件处理方法:
private void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) { var textBox = sender as TextBox; if (textBox == null) return; // 获取TextBox绑定的Item对象 var currentItem = textBox.DataContext as Item; if (currentItem != null) { // 将对应的Item设为ListBox的选中项 itemListBox.SelectedItem = currentItem; } }
关键说明
- 修正语法错误:把原XAML中
Name-"theTextBox"的笔误改成了Name="theTextBox",避免控件无法被正常识别。 - 重构高亮逻辑:现在ListBoxItem的高亮由
IsSelected属性驱动,只要Item处于选中状态,就会持续显示浅绿色背景,不受外部焦点影响。 - 焦点联动选中:通过
IsKeyboardFocusWithin触发器,确保焦点进入内部TextBox时自动选中对应Item;同时在TextBox获得焦点的事件中手动同步选中状态,保证逻辑的一致性。 - 保留原有体验:
KeyboardNavigation.TabNavigation="Cycle"的设置依然生效,你可以继续用Tab键在各个内部TextBox间循环导航。
这样修改后,即使焦点移到外部的theTextBox,之前选中的ListBoxItem仍然会保持高亮状态,完美解决你的问题!
内容的提问来源于stack exchange,提问作者hjyanghj
相关产品推荐
相关产品推荐

