Первые консервы исходное отслеживание стека исключения, второе заменяет его текущим местоположением.
Поэтому первое БЕЗУСЛОВНО лучше.
Это можно сделать в xaml, установив следующие два свойства.
<Style TargetType="ListBox" >
<Setter Property="KeyboardNavigation.TabNavigation" Value="Continue" />
</Style>
<Style TargetType="ListBoxItem">
<Setter Property="IsTabStop" Value="False" />
</Style>
Полное объяснение см. В сообщении в блоге Дерека Уилсона .
РЕДАКТИРОВАТЬ
В частности, после комментария:
private void ListBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Tab)
{
ListBox lb = sender as ListBox;
if(lb == null) return;
if(lb.SelectedIndex < lb.Items.Count - 1)
{
GiveItemFocus(lb, lb.SelectedIndex + 1, typeof(TextBox));
e.Handled = true;
}
}
}
private void GiveItemFocus(ListBox lb, int index, Type descentdantType)
{
if(lb.Items.Count >= index || index < 0)
{
throw new ArgumentException();
}
ListBoxItem lbi = (ListBoxItem) lb.ItemContainerGenerator.ContainerFromIndex(index);
lb.UnselectAll();
lbi.IsSelected = true;
UIElement descendant = (UIElement) FindVisualDescendant(lbi, o => o.GetType() == descentdantType);
descendant.Focus();
}
private static DependencyObject FindVisualDescendant(DependencyObject dependencyObject, Predicate<bool> condition)
{
//implementation not provided, commonly used utility
}
Установка e.Handled
на true гарантирует, что при нажатии табуляции будет обрабатываться только ваш обработчик, и поведение по умолчанию не будет активировано.