2010-05-07 11 views
0

J'ai une collection (VariableValueCollection) de type personnalisé VariableValueViewModel objets liés à un ListView. WPF Suivre:Récupérer un élément TextBox créé dynamiquement et le mettre au point

<ListView ItemsSource="{Binding VariableValueCollection}" Name="itemList"> 
    <ListView.Resources> 
     <DataTemplate DataType="{x:Type vm:VariableValueViewModel}"> 
      <Grid> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="180"></ColumnDefinition> 
       </Grid.ColumnDefinitions> 
       <TextBox TabIndex="{Binding Path=Index, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Grid.Column="0" Name="tbValue" Focusable="True" LostFocus="tbValue_LostFocus" GotFocus="tbValue_GotFocus" KeyDown="tbValue_KeyDown"> 
        <TextBox.Text> 
         <Binding Path="Value" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay"> 
          <Binding.ValidationRules> 
           <ExceptionValidationRule></ExceptionValidationRule> 
          </Binding.ValidationRules> 
           </Binding> 
        </TextBox.Text> 
       </TextBox>        
      </Grid> 
     </DataTemplate> 
    </ListView.Resources> 
</ListView> 

Mon but est d'ajouter une nouvelle ligne quand j'appuyez sur « Entrée » sur la dernière ligne, et mise au point de la nouvelle ligne. Pour ce faire, je vérifie que la ligne est la dernière ligne et ajoute une nouvelle ligne dans ce cas. Mais je ne sais pas comment concentrer la nouvelle zone de texte ...

Voici la méthode KeyPressed:

private void tbValue_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.Key == System.Windows.Input.Key.Enter) 
     { 

      DependencyObject obj = itemList.ContainerFromElement((sender as TextBox));     
      int index = itemList.ItemContainerGenerator.IndexFromContainer(obj); 
      if(index == (VariableValueCollection.Count - 1)) 
      { 
       // Create a VariableValueViewModel object and add to collection. In binding, that create a new list item with a new TextBox 
       ViewModel.AddNewRow(); 

       // How to set cursor and focus last row created? 
      } 

     } 
    } 

Répondre

0

je pourrais être mal compris votre problème, mais puisque vous liez votre ListView au VariableValueCollection, tout changement vous faites à la collection sous-jacente sera reflétée dans votre ListView.

Vous devriez juste pouvoir faire quelque chose comme ça de votre gestionnaire d'événements keydown:

var newItem = new VariableValueViewModel(); 
VariableValueCollection.Add(newItem); 

itemList.SelectedItem = newItem; 

EDIT: Comment concentrer la zone de texte:

La méthode ci-dessous vous permet de trouver un contrôle enfant dans un arbre visuel:

/// <summary> 
/// Finds the first child in the visual tree by type. 
/// </summary> 
public static T TryFindChild<T>(DependencyObject parent, Func<T, bool> predicate = null) where T : class { 
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { 
     var child = VisualTreeHelper.GetChild(parent, i); 
     if ((child is T) && (predicate!=null && predicate(child as T))) { 
      return (T)((object)child); 
     } else { 
      T result = TryFindChild<T>(child, predicate); 
      if (result != null) 
       return result; 
     } 
    } 
    return null; 
} 

maintenant vous pouvez faire quelque chose comme ceci:

itemList.ItemContainerGenerator.ContainerFromItem(newItem); 
TextBox textBox = TryFindChild<TextBox>(newItem) as TextBox; 
if (textBox != null) { 
    textBox.Focus(); 
} 
+0

En pratique, chaque élément que j'ajoute à ma collection, la liaison crée un nouveau TextBox dans ListView. Élément connu, comment mettre le curseur d'édition clignotant sur la TextBox associée? – user335444

+0

J'ai mis à jour ma réponse ci-dessus avec une méthode qui devrait vous permettre de le faire. –