如果 ListBox 使用数据绑定,如何在加载时正确设置焦点?

Posted

技术标签:

【中文标题】如果 ListBox 使用数据绑定,如何在加载时正确设置焦点?【英文标题】:How can I set the focus to a ListBox properly on load if it uses databinding? 【发布时间】:2011-01-17 23:53:57 【问题描述】:

我通常在 Loaded 事件处理程序中调用 myControl.Focus(),但这似乎不适用于数据绑定到自定义对象列表的 ListBox。当我启动我的应用程序时,ListBox 的第一项被选中,但焦点在其他地方。

我认为这可能是因为在将数据绑定项加载到其中之前设置了焦点...但是以下代码显示确实存在项,因为ctrlItemsCount 显示数字 8。

在这种情况下如何设置初始焦点,通常设置初始焦点的正确位置是什么?

private void onLoad(object sender, RoutedEventArgs e) 
        if (ctrlCountries.Items.Count > 0) 
             ctrlItemsCount.Text = ctrlCountries.Items.Count;
             ctrlCountries.SelectedIndex = 0;
             FocusManager.SetFocusedElement(this, ctrlCountries);
        

  

编辑:我已将此代码移动到实际ListBox 本身的加载事件中。它几乎可以工作 - 现在焦点在ListBox 上,但我仍然需要在项目#0 有键盘光标之前按一次键盘向下。换句话说,由于某种原因,焦点或光标比第 0 项高 1 个等级:

private void onCountriesLoaded(object sender, RoutedEventArgs e) 
    ctrlCountries.SelectedIndex = 0;
    FocusManager.SetFocusedElement(this, ctrlCountries);
    Keyboard.Focus();

【问题讨论】:

【参考方案1】:

如果您想关注列表框中的第一个元素,您必须将焦点设置到第一个 ListBoxItem 容器。例如:

if (myListBox.Items.Count > 0)
 
   ListBoxItem item = (ListBoxItem)myListBox.ItemContainerGenerator.ContainerFromIndex(0);
   FocusManager.SetFocusedElement(this /* focus scope region */, item);

您仍然必须确保 ListBox 控件首先收到了它的 Loaded 事件。还有许多其他事件可用于处理与列表框项相关的更新。查看 MSDN 中的ItemContainerGenerator。

【讨论】:

有效!几乎...如果我使用“Keyboard.Focus(item);”,它应该可以 100% 工作而不是 FocusManager。这很奇怪,因为 MSDN 说 FocusManager 将设置逻辑焦点并尝试设置键盘焦点。我是否学到了正确的教训 Keyboard.Focus(item) 是我应该始终使用的?【参考方案2】:

FocusManager.SetFocusedElement 方法提供逻辑焦点,但不提供键盘焦点。您可以使用Keyboard.Focus 方法将键盘焦点赋予元素。请查看this page,了解有关 WPF 中焦点管理的更多详细信息。

【讨论】:

我添加了 Keyboard.Focus(ctrlCountries);它不起作用。请注意,如果我添加一个单独使用焦点管理器设置焦点的按钮单击事件处理程序,它就可以工作。 也就是说,下面的代码没有把焦点放在列表框的第一项上: private void onLoad(object sender, RoutedEventArgs e) FocusManager.SetFocusedElement(this, ctrlCountries);键盘.Focus(ctrlCountries); 在 ListBox 完全加载后执行(即当 ctrlCountries.Loaded 事件发生时) 谢谢,现在好多了。但是光标仍然在 ListBox 的外部(即它的边框似乎有焦点),所以我必须在选择第一个列表框项之前点击 DOWN。 我想你也可以尝试设置逻辑焦点: var item = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromIndex(selectedIndex); FocusManager.SetFocusedElement(this, item); Keyboard.Focus(item);

以上是关于如果 ListBox 使用数据绑定,如何在加载时正确设置焦点?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 SQLCe Db 检索数据并将数据绑定到 ListBox

2022-03-23 WPF面试题 ListBox 与 ListView - 如何选择以及何时进行数据绑定?

2022-03-23 WPF面试题 ListBox 与 ListView - 如何选择以及何时进行数据绑定?

WPF如何更改xaml代码里ListBox的数据绑定

如何将字符串列表数据绑定到 WPF/WP7 中的 ListBox?

WPF 将 ListBox 绑定到枚举,显示描述属性