当选择ListBoxItem时,如何将焦点设置到ItemTemplate中的控件?

Gre*_*som 3 wpf focus datatemplate listboxitem

我有一个ListBox,它使用DataTemplate显示对象.DataTemplate包含一个TextBox.当用户选择ListBox中的项目时,我想将焦点设置为所选项目的TextBox.

我已经能够通过处理ListBox.SelectionChanged来部分实现这一点,但它仅在用户单击ListBox以选择项时才有效 - 如果用户选中ListBox并使用箭头键选择项,则它不起作用即使TextBox.Focus()调用.

当用户使用键盘选择项目时,如何将焦点设置到TextBox?

这是ListBox的标记:

<ListBox Name="lb1" SelectionChanged="ListBox_SelectionChanged" ItemsSource="{Binding Items}" >
    <ListBox.ItemTemplate>
        <DataTemplate >
            <TextBox></TextBox>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)

这是处理代码:

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ListBoxItem lbi = (ListBoxItem)this.lb1.ItemContainerGenerator.ContainerFromItem(this.lb1.SelectedItem);
    Visual v = GetDescendantByType<TextBox>(lbi);
    TextBox tb = (TextBox)v;
    tb.Focus();
}
Run Code Online (Sandbox Code Playgroud)

And*_*ana 6

要做到这一点的一种方法是更换tb.Focus()SelectionChanged与事件处理程序:

tb.Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(delegate()
        {
            tb.Focus();
        }));
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为调用BeginInvoke调度程序会导致指定的代码在调度程序可用时运行 - 即在WPF内部完成事件处理之后.

问题在于,当您在列表项具有焦点时首次按下箭头后,下一个列表项将被选中,其文本框将变为焦点,您将无法使用向下箭头再次移动选择.您可能也想编写一些代码来处理这种情况.