2013-05-08 2 views
6

У меня есть окно со следующим XAML:Почему не работает вкладка между/внутри TreeView?

<Window x:Class="TestDemoApp.TreeViewWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="TreeViewWindow" Height="300" Width="300"> 
    <Window.Resources> 
     <Style TargetType="Control" x:Key="FocusedStyle"> 
      <Setter Property="Control.Template"> 
       <Setter.Value> 
        <ControlTemplate> 
         <Rectangle StrokeThickness="1" 
           Stroke="Red" 
           StrokeDashArray="1 2 3 4" 
           SnapsToDevicePixels="true"/> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 

     <Style TargetType="TreeViewItem"> 
      <Setter Property="IsTabStop" Value="True"/> 
      <Setter Property="Focusable" Value="True"/> 
      <Setter Property="FocusVisualStyle" Value="{StaticResource FocusedStyle}"/> 
      <Setter Property="KeyboardNavigation.TabNavigation" Value="Continue"/> 
     </Style> 
     <Style TargetType="ListViewItem"> 
      <Setter Property="IsTabStop" Value="True"/> 
      <Setter Property="Focusable" Value="True"/> 
      <Setter Property="FocusVisualStyle" Value="{StaticResource FocusedStyle}"/> 
      <Setter Property="KeyboardNavigation.TabNavigation" Value="Continue"/> 
     </Style> 
    </Window.Resources> 

    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*"/> 
      <RowDefinition Height="*"/> 
     </Grid.RowDefinitions> 

     <ListView TabIndex="1" BorderThickness="5" Focusable="True" IsTabStop="True" KeyboardNavigation.TabNavigation="Continue" FocusVisualStyle="{StaticResource FocusedStyle}"> 
      <ListViewItem TabIndex="2" Content="List Item 1"/> 
      <ListViewItem TabIndex="3" Content="List Item 2"/> 
     </ListView> 

     <TreeView TabIndex="6" BorderThickness="5" Focusable="True" IsTabStop="True" KeyboardNavigation.TabNavigation="Continue" Grid.Row="1" FocusVisualStyle="{StaticResource FocusedStyle}"> 
      <TreeView.Items> 
       <TreeViewItem TabIndex="7" Header="Tree Item 1"> 
        <TreeViewItem Header="Tree Item 11"></TreeViewItem> 
        <TreeViewItem Header="Tree Item 12"/> 
       </TreeViewItem> 
       <TreeViewItem Header="Tree Item 2"> 
       </TreeViewItem> 
      </TreeView.Items> 
     </TreeView> 
    </Grid> 
</Window> 

Когда я запускаю программу, то порядок обхода:

 
1. List View 
2. List Item 1 
3. List Item 2 
4. Tree View 
5. Tree Item 1 
6. Tree Item 2 

7. List View (#1) 
8. List Item 1 (#2) 
9. List Item 2 (#3) 
10. Tree Item 2 (6#) 

11+ Repeat #7 - #10 

Ожидаемое поведение является то, что она повторяется из # 1 до # 6 на дальнейшие итерации, однако вместо этого он пропускает # 4 и # 5 на любые последующие итерации.

Почему это? И как я могу это исправить?

ответ

3

Wow, это UGLY. Древовидное представление WPF - моя любимая цель для этого прилагательного во многих отношениях, но я не сталкивался с этой конкретной проблемой раньше.

Не думаю, что вы можете сделать лучше, чем Continue, для KeyboardNavigation.TabNavigation, единственная другая возможность - Local, и это тоже не работает. См. this msdn article. Кроме того, комбинации, такие как Cycle по пунктам и Continue на контроле, не дали желаемого результата для меня.

Совершенно очевидно, что выбранный элемент сохраняется в древовидной структуре, когда фокус возвращается к списку, а когда древовидный объект получает фокус в следующий раз, он переходит непосредственно к ранее выбранному элементу (элемент дерева 2) в отличие от списка, который сохраняет выбор, но правильно фокусирует управление сначала, а затем элементы.

Таким образом, быстрый и грязный хак, который может сработать для вас, заключается в удалении выделения из дерева, когда он теряет фокус. К сожалению, событие срабатывает каждый раз, когда выбранный элемент изменяется, но взлом работает все же.

<TreeView (...) LostFocus="TreeView_LostFocus"> 

код позади:

private void TreeView_LostFocus(object sender, RoutedEventArgs e) 
{ 
    TreeView tv = (TreeView)sender; 
    TreeViewItem item = tv.SelectedItem as TreeViewItem; 
    if (item != null) 
     item.IsSelected = false; 
} 
Смежные вопросы