2010-05-22 2 views
54

Я пытаюсь установить позицию каретки/курсора в конец end значения строки в текстовом поле WPF, когда я открываю свое окно в первый раз , Я использую FocusManager, чтобы настроить фокус на моем текстовом поле, когда откроется мое окно.Установить позицию курсора/курсора в конец строкового значения Текстовое поле WPF

Ничто не работает. Есть идеи?

Примечание. Я использую шаблон MVVM, и я включил только часть XAML из своего кода.

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

ответ

76

Вы можете установить позицию курсора, используя CaretIndex свойство TextBox. Пожалуйста, имейте в виду, что это не DependencyProperty. Тем не менее, вы все равно можете установить его в XAML как это:

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

Пожалуйста, не забудьте установить CaretIndexпослеText собственности или иначе это не будет работать. Таким образом, это, вероятно, не сработает, если вы привязаетесь к Text, как в вашем примере. В этом случае просто используйте такой код.

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

Да, я пытался связать с CaretIndex, и это не удалось. Добавление кода в код-код в событии, загруженном окном, отлично поработало. Спасибо. – Zamboni

16

Вы также можете создать Поведение, которое, будучи по-прежнему имеющим код, имеет то преимущество, что оно может использоваться повторно.

Пример простого класса поведения, с помощью события фокуса текстового поля:

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

Затем в вашем XAML, вы присоедините поведение следующим образом:

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

Это лучшее решение. Установка курсора вручную - это боль в заднице. – Darkhydro

2

Если текстовое поле (WinForms) многострочное с вертикальной полосой прокрутки вы можете попробовать это:

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

Примечание: В WPF .ScrollToC ist() не является членом TextBox.

1

В случае многострочного TextBox установки курсора недостаточно. Попробуйте следующее:

NumberOfDigits.ScrollToEnd(); 
+0

Только ответ на код - это не хорошие ответы, добавьте несколько строк, чтобы объяснить, в чем проблема, и почему ваш код исправил это – MikeT

2

Это сработало для меня. Я также использую шаблон MVVM. Тем не менее, моя цель использования MMVM заключается в том, чтобы сделать модульное тестирование возможным и упростить обновление моего интерфейса (слабо связанного). Я не вижу, чтобы я тестировал позицию курсора, поэтому я не против прибегать к коду, стоящему за этой простой задачей.

public ExpeditingLogView() 
    { 
     InitializeComponent(); 

     this.Loaded += (sender, args) => 
     {         
      Description.CaretIndex = Description.Text.Length; 
      Description.ScrollToEnd(); 
      Description.Focus(); 
     }; 
    } 
Смежные вопросы