2013-05-08 9 views
6

Mam okno z poniższym XAML:Dlaczego kolejność kart między/wewnątrz widoku drzewa nie działa?

<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> 

Kiedy uruchamiam program, kolejność karta jest:

 
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 

Oczekiwane zachowanie jest, że to powtarza się od # 1 do # 6 na kolejne iteracje, zamiast tego pomija # 4 i # 5 w kolejnych iteracjach.

Dlaczego tak jest? I jak mogę to naprawić?

Odpowiedz

3

Wow, to jest UGLY. Widok drzewa WPF jest moim ulubionym celem dla tego przymiotnika pod wieloma względami, ale nie spotkałem się wcześniej z tym konkretnym problemem.

Nie sądzę, że można zrobić lepiej niż Continue dla KeyboardNavigation.TabNavigation, jedyną inną możliwością jest Local, a to też nie działa. Zobacz this msdn article. Również kombinacje takie jak Cycle na elementach i Continue na formancie nie przyniosły pożądanego wyniku dla mnie.

Całkiem oczywiste, wybrany element jest zachowywany w widoku drzewa, gdy fokus wraca do widoku listowego, a gdy widok drzewa zostaje skupiony następnym razem, przekazuje fokus bezpośrednio do wcześniej wybranego elementu (element drzewa 2), w przeciwieństwie do listy, która zachowuje wybór, ale najpierw prawidłowo ustawia kontrolę, a następnie elementy.

Szybkim i brudnym narzędziem, które może ci pomóc, jest usunięcie zaznaczenia z widoku drzewa, gdy utracisz fokus. Niestety zdarzenie jest uruchamiane za każdym razem, gdy wybrany element ulega zmianie, ale mimo to działa.

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

kod za:

private void TreeView_LostFocus(object sender, RoutedEventArgs e) 
{ 
    TreeView tv = (TreeView)sender; 
    TreeViewItem item = tv.SelectedItem as TreeViewItem; 
    if (item != null) 
     item.IsSelected = false; 
}