2010-05-22 9 views
54

J'essaie de définir la position curseur/curseur sur fin de la valeur de chaîne dans ma zone de texte WPF lorsque j'ouvre ma fenêtre pour la première fois . J'utilise le FocusManager pour mettre l'accent sur ma zone de texte lorsque ma fenêtre s'ouvre.Définir la position du curseur/curseur à la fin de la valeur de chaîne WPF textbox

Rien ne semble fonctionner. Des idées?

Remarque, j'utilise le modèle MVVM et j'ai inclus seulement une partie du code XAML de mon code.

<Window 
    FocusManager.FocusedElement="{Binding ElementName=NumberOfDigits}" 
    Height="400" Width="800"> 

    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition/> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition/> 
      <RowDefinition/> 
     </Grid.RowDefinitions> 

     <TextBox Grid.Column="0" Grid.Row="0" 
       x:Name="NumberOfDigits" 
       IsReadOnly="{Binding Path=IsRunning, Mode=TwoWay}" 
       VerticalContentAlignment="Center" 
       Text="{Binding Path=Digits, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 
     <Button Grid.Column="0" Grid.Row="1" 
       Margin="10,0,10,0" 
       IsDefault="True" 
       Content="Start" 
       Command="{Binding StartCommand}"/> 
    </Grid> 
</Window> 

Répondre

76

Vous pouvez régler la position de caret en utilisant la propriété CaretIndex d'un TextBox. S'il vous plaît gardez à l'esprit que ce n'est pas un DependencyProperty. Néanmoins, vous pouvez toujours le mettre en XAML comme ceci:

<TextBox Text="123" CaretIndex="{x:Static System:Int32.MaxValue}" /> 

S'il vous plaît rappelez-vous de mettre CaretIndexaprèsText propriété ou bien elle ne fonctionnera pas. Ainsi, il ne fonctionnera probablement pas si vous vous liez à Text comme dans votre exemple. Dans ce cas, utilisez simplement le code-behind comme ceci.

NumberOfDigits.CaretIndex = NumberOfDigits.Text.Length; 
+2

Oui, j'ai essayé de lier CaretIndex et cela a échoué. L'ajout de votre code au code-behind dans l'événement Window Loaded a bien fonctionné. Merci. – Zamboni

16

Vous pouvez également créer un comportement qui, tout en étant codé, a l'avantage d'être réutilisable.

Exemple d'une simple classe de comportement, en utilisant l'événement de mise au point de la zone de texte:

class PutCursorAtEndTextBoxBehavior: Behavior<UIElement> 
{ 
    private TextBox _textBox; 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     _textBox = AssociatedObject as TextBox; 

     if (_textBox == null) 
     { 
      return; 
     } 
     _textBox.GotFocus += TextBoxGotFocus; 
    } 

    protected override void OnDetaching() 
    { 
     if (_textBox == null) 
     { 
      return; 
     } 
     _textBox.GotFocus -= TextBoxGotFocus; 

     base.OnDetaching(); 
    } 

    private void TextBoxGotFocus(object sender, RoutedEventArgs routedEventArgs) 
    { 
     _textBox.CaretIndex = _textBox.Text.Length; 
    } 
}  

Ensuite, dans votre XAML, vous associez le comportement comme ceci:

<TextBox x:Name="MyTextBox" Text="{Binding Value}"> 
     <i:Interaction.Behaviors> 
      <behaviors:PutCursorAtEndTextBoxBehavior/> 
     </i:Interaction.Behaviors> 
    </TextBox> 
+1

C'est la meilleure solution. Régler le curseur manuellement est une douleur dans le cul. – Darkhydro

2

Si votre zone de texte (WinForms) est multiligne avec une barre de défilement vertical, vous pouvez essayer ceci:

textbox1.Select(textbox1.Text.Length-1, 1); 
textbox1.ScrollToCaret(); 

Remarque: WPF .ScrollToC aret() n'est pas un membre de TextBox.

1

Dans le cas d'un multiligne TextBox, le curseur de réglage n'est pas suffisant. Essayez ceci:

NumberOfDigits.ScrollToEnd(); 
+0

Les réponses uniquement au code ne sont pas de bonnes réponses, ajoutez quelques lignes pour expliquer le problème et pourquoi votre code l'a corrigé – MikeT

2

Cela a fonctionné pour moi. J'utilise aussi le pattern MVVM. Cependant, mon but pour l'utilisation d'un MMVM est de rendre les tests unitaires possibles et de faciliter la mise à jour de mon interface utilisateur (faiblement couplée). Je ne me vois pas tester la position du curseur par l'unité, donc cela ne me dérange pas de recourir au code derrière pour cette tâche simple.

public ExpeditingLogView() 
    { 
     InitializeComponent(); 

     this.Loaded += (sender, args) => 
     {         
      Description.CaretIndex = Description.Text.Length; 
      Description.ScrollToEnd(); 
      Description.Focus(); 
     }; 
    } 
Questions connexes