我有一个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>
以下是处理代码:
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();
}
答案 0 :(得分:6)
执行此操作的一种方法是将tb.Focus()
事件处理程序中的SelectionChanged
替换为:
tb.Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(delegate()
{
tb.Focus();
}));
这是有效的,因为调度程序上调用BeginInvoke
会导致指定代码在调度程序可用时运行 - 即在WPF内部完成事件处理之后。
问题在于,当您在列表项具有焦点时首次按下箭头后,下一个列表项将被选中,其文本框将变为焦点,您将无法使用向下箭头再次移动选择。您可能也想编写一些代码来处理这种情况。