开发者

How do I set focus to a control within the ItemTemplate when the ListBoxItem is selected?

I have a ListBox which presents objects using a DataTemplate. The DataTemplate开发者_C百科 contains a TextBox. When the user selects an item in the ListBox, I would like to set focus to the TextBox for the selected item.

I have been able to partially achieve this by handling ListBox.SelectionChanged, but it only works when the user clicks on the ListBox to select the item - it does not work if the user tabs into the ListBox and uses the arrow keys to select the item even though TextBox.Focus() is invoked.

How can I set focus to the TextBox when the user uses the keyboard to select an item?

Here is the markup for the ListBox:

<ListBox Name="lb1" SelectionChanged="ListBox_SelectionChanged" ItemsSource="{Binding Items}" >
    <ListBox.ItemTemplate>
        <DataTemplate >
            <TextBox></TextBox>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Here is the handling code:

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();
}


One way to do this is to replace the tb.Focus() from your SelectionChanged event handler with:

tb.Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(delegate()
        {
            tb.Focus();
        }));

This works because calling BeginInvoke on the dispatcher causes the specified code to run when the dispatcher is available - i.e. after WPF has finished handling the events internally.

The catch is that, after you first press down arrow when a list item has focus, the next list item will became selected, its textbox will become focused and you will not be able to move selection again with the down arrow. You'll probably want to write some code to handle this case too.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜