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