2010-05-22 8 views
54

Sto provando a impostare la posizione cursore/cursore sulla fine del valore di stringa nella mia casella di testo WPF quando apro la finestra per la prima volta . Io uso il FocusManager per impostare l'attenzione sulla mia casella di testo quando si apre la mia finestra.Impostare la posizione cursore/cursore alla fine del valore stringa WPF textbox

Nulla sembra funzionare. Qualche idea?

Nota, sto utilizzando il pattern MVVM e ho incluso solo una parte di XAML dal mio codice.

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

risposta

76

È possibile impostare la posizione del cursore utilizzando CaretIndex proprietà di un TextBox. Si prega di tenere presente che questo non è un DependencyProperty. Tuttavia, si può ancora impostare in XAML come questo:

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

Si prega di ricordarsi di impostare CaretIndexdopoText proprietà o altrimenti non funzionerà. Quindi probabilmente non funzionerà se ti leghi allo Text come nell'esempio. In tal caso, usa semplicemente code-behind come questo.

+2

Sì, ho provato a eseguire il binding a CaretIndex e non è riuscito. L'aggiunta del codice al code-behind in Window Loaded Event ha funzionato alla grande. Grazie. – Zamboni

16

È inoltre possibile creare un comportamento, che, pur essendo ancora code-behind, ha il vantaggio di essere riutilizzabile.

Esempio di una semplice classe comportamento, utilizzando l'evento di messa a fuoco della casella di testo:

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

Poi, nel vostro XAML, si collega il comportamento in questo modo:

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

Questa è la soluzione migliore. L'impostazione manuale del cursore è un rompiscatole. – Darkhydro

2

Se il testo (WinForms) è più righe con una barra di scorrimento verticale si può provare questo:

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

Nota: In WPF .ScrollToC aret() non è un membro di TextBox.

1

In caso di multilinea TextBox il cursore di impostazione non è sufficiente. Prova questo:

NumberOfDigits.ScrollToEnd(); 
+0

Le risposte al solo codice non sono buone risposte, aggiungi alcune righe per spiegare qual è il problema e perché il tuo codice lo ha risolto – MikeT

2

Questo ha funzionato per me. Sto anche usando il pattern MVVM. Tuttavia, il mio scopo per l'utilizzo di un MMVM è rendere possibile il test delle unità e semplificare l'aggiornamento della mia interfaccia utente (accoppiato in modo lasco). Non mi vedo unità testare la posizione del cursore, quindi non mi dispiace ricorrere al codice dietro per questo semplice compito.

public ExpeditingLogView() 
    { 
     InitializeComponent(); 

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