WinUI 3 ListView实现仅指定项可选可响应按键且其他项禁用
WinUI 3 ListView 特定项交互与焦点保持解决方案
核心处理逻辑
- 改用
ListViewSelectionMode.Single替代None,保留选中状态,确保最后一项能维持焦点 - 给前至倒数第二项设置
IsEnabled=false,同时拦截它们的焦点获取行为,防止点击后夺走最后一项的焦点 - 强制默认选中最后一项,并在点击禁用项后自动将焦点切回最后一项
具体实现代码
1. ListView初始化配置方法
internal static void ConfigureMyListView(ListView view) { // 设置单选模式,保留选中状态 view.SelectionMode = ListViewSelectionMode.Single; view.IsItemClickEnabled = true; // 遍历配置每一项的状态 for (int i = 0; i < view.Items.Count; i++) { if (view.ContainerFromIndex(i) is ListViewItem item) { // 前至倒数第二项禁用,并拦截焦点 if (i < view.Items.Count - 1) { item.IsEnabled = false; // 禁用项获取焦点时,强制切回最后一项 item.GotFocus += (s, e) => { var lastItem = view.ContainerFromIndex(view.Items.Count - 1) as ListViewItem; lastItem?.Focus(FocusState.Programmatic); }; } // 最后一项默认选中并获取焦点 else { item.IsSelected = true; item.Focus(FocusState.Programmatic); } } } // 监听列表点击,确保点击禁用项后焦点回到最后一项 view.ItemClick += (s, e) => { var lastItem = view.ContainerFromIndex(view.Items.Count - 1) as ListViewItem; if (lastItem != null && !lastItem.IsFocused) { lastItem.Focus(FocusState.Programmatic); } }; }
2. 最后一项空格键事件处理
在页面或控件的Loaded事件中绑定按键逻辑:
private void MyListView_Loaded(object sender, RoutedEventArgs e) { var listView = sender as ListView; if (listView == null || listView.Items.Count == 0) return; var lastItem = listView.ContainerFromIndex(listView.Items.Count - 1) as ListViewItem; lastItem?.KeyDown += LastItem_KeyDown; } private void LastItem_KeyDown(object sender, KeyRoutedEventArgs e) { if (e.Key == Windows.System.VirtualKey.Space) { var targetItem = sender as ListViewItem; // 此处添加颜色变化逻辑,示例修改背景色 targetItem.Background = new SolidColorBrush(Colors.DarkOrange); e.Handled = true; } }
关键细节说明
- 用
ContainerFromIndex获取ListViewItem,避免直接遍历Items时的类型转换问题(Items中可能是数据模型而非控件实例) - 通过拦截禁用项的
GotFocus事件,强制焦点保持在最后一项,确保按键事件能被正确响应 ListViewSelectionMode.Single既保留选中状态,又因其他项禁用而仅允许最后一项被选中
内容的提问来源于stack exchange,提问作者Mahesh
相关产品推荐
相关产品推荐

