2017-06-29 4 views
0

J'ai un contrôle WPF défini comme suit:WPF: Le passage d'une cellule à l'autre lorsque vous appuyez sur Entrée dans un ItemsControl

 <ItemsControl ItemsSource="{Binding DutyValueBinders}" IsEnabled="{Binding Enabled}"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <StackPanel Orientation="Horizontal"/> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <TextBox Text="{Binding Value, TargetNullValue=''}" Width="50"></TextBox> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 

Cela produit une grille, qui ressemble à ceci:

Grid with data

Ainsi, bien qu'il n'y ait qu'une seule zone de texte définie dans le code XAML, l'utilisateur voit une grille. Ce que je veux faire est, après que l'utilisateur a tapé une valeur et appuyé sur Entrée ou Retour, le focus devrait passer à la cellule suivante et ainsi de suite jusqu'à ce que la fin de la grille soit atteinte. J'ai essayé de mettre cette routine dans le code derrière (copié à partir d'un autre thread sur stackoverflow):

private void UserControl_PreviewKeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.Key != Key.Enter || (!e.IsToggled && sender is Button)) return; 
     var request = new TraversalRequest(FocusNavigationDirection.Next); 
     var keyboardFocus = Keyboard.FocusedElement as UIElement; 

     if (keyboardFocus == null) return; 
     keyboardFocus.MoveFocus(request); 
     e.Handled = true; 
    } 

Modifiés l'en-tête du XAML comme suit:

<UserControl ... 
      (Other references) 
      ... 
      d:DesignHeight="300" d:DesignWidth="300" PreviewKeyDown="UserControl_PreviewKeyDown"> 

Le problème est, car il n'y a qu'une seule zone de texte dans la définition XAML, il n'y a pas d'ordre tabindex à suivre, et lorsque vous appuyez sur Entrée, le curseur disparaît.

Y a-t-il un moyen de le faire, à part d'abandonner complètement le XAML et de recommencer avec un autre type de contrôle?

+0

Je ne comprends pas comment cela peut produire 'ItemsControl' plusieurs lignes. – Maxim

Répondre

1

Que diriez-vous gérer l'événement PreviewKeyDown pour le ItemsControl comme ça ?:

<ItemsControl ItemsSource="{Binding DutyValueBinders}" IsEnabled="{Binding Enabled}" 
       PreviewKeyDown="ItemsControl_PreviewKeyDown"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel Orientation="Horizontal"/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <TextBox Text="{Binding Value, TargetNullValue=''}" Width="50"></TextBox> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

private void ItemsControl_PreviewKeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Enter) 
    { 
     TextBox textBox = Keyboard.FocusedElement as TextBox; 
     if (textBox != null) 
     { 
      textBox.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); 
     } 
    } 
}