在 ListBox 中设置焦点会破坏键盘导航

9

在程序中选择了 ListBox 项目后,需要按下上/下方向键两次才能移动选择。有什么建议吗?

视图:

<ListBox Name="lbActions" Canvas.Left="10" Canvas.Top="10"
               Width="260" Height="180">
        <ListBoxItem Name="Open" IsSelected="true" Content="Open"></ListBoxItem>
        <ListBoxItem Name="Enter" Content="Enter"></ListBoxItem>
        <ListBoxItem Name="Print" Content="Print"></ListBoxItem>
</ListBox>

代码:

public View()
{
   lbActions.Focus();
   lbActions.SelectedIndex = 0; //not helps
   ((ListBoxItem) lbActions.SelectedItem).Focus(); //not helps either
}
3个回答

14

不要将焦点设置到ListBox上...而应该将焦点设置到已选中的ListBoxItem上。这样可以解决“需要按两次键盘”这个问题:

if (lbActions.SelectedItem != null)
    ((ListBoxItem)lbActions.SelectedItem).Focus();
else
    lbActions.Focus();
如果你的 ListBox 包含除 ListBoxItem 之外的其他内容,你可以使用 lbActions.ItemContainerGenerator.ContainerFromIndex(lbActions.SelectedIndex) 来获取自动生成的 ListBoxItem。
如果你想在窗口初始化期间发生这种情况,你需要将代码放在 Loaded 事件中,而不是构造函数中。示例(XAML):
<Window ... Loaded="Window_Loaded">
    ...
</Window>

根据你的问题,以下是代码示例:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        lbActions.Focus();
        lbActions.SelectedIndex = 0;
        ((ListBoxItem)lbActions.SelectedItem).Focus();
    }

我已经在XAML中选择了项目 "IsSelected="true"。我在代码中提供了额外的选择,这样可能更明显我想要做什么 "lbActions.SelectedIndex = 0;"。 - StreamT
我的答案仍然有效,只需将代码放在 SelectedIndex = 0 之后 - Heinzi
不起作用。项目已选择,这不是问题。键盘导航在之后无法正常工作。 - StreamT
啊,我现在才意识到你想要初始焦点(而不是响应某个按钮点击后获得焦点)。好的,我会研究一下。 - Heinzi
将项目选择代码移动到Windows Loaded事件中可以解决该问题。 - StreamT

1

你也可以在XAML中轻松实现这一点。请注意,这将仅设置逻辑焦点。

例如:

<Grid FocusManager.FocusedElement="{Binding ElementName=itemlist, Path=SelectedItem}">
    <ListBox x:Name="itemlist" SelectedIndex="1">
        <ListBox.Items>
            <ListBoxItem>One</ListBoxItem>
            <ListBoxItem>Two</ListBoxItem>
            <ListBoxItem>Three</ListBoxItem>
            <ListBoxItem>Four</ListBoxItem>
            <ListBoxItem>Five</ListBoxItem>
            <ListBoxItem>Six</ListBoxItem>
        </ListBox.Items>
    </ListBox>
</Grid>

-1

似乎 ListBox 控件有两个焦点级别:ListBox 本身和 ListBoxItem。就像 Heinzi 所说的那样,直接为 ListBoxItem 设置焦点将避免您必须点击两次方向键才能浏览所有 ListBoxItems 的情况。

经过几个小时的工作,我发现了这一点,现在我的应用程序完美地运行。


【评论】嗨,DanielGao,我投了反对票,因为它没有为Heinzi已经给出的答案增添任何内容。如果你想赞扬Heinzi,最好使用评论! - Goodies

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接