Установите позицию курсора/курсора в конец текстового поля WPF с строковым значением
Я пытаюсь установить позицию курсора/курсора в конец строкового значения в текстовом поле WPF, когда я открываю свое окно в первый раз. Я использую FocusManager, чтобы настроить фокус на моем текстовом поле, когда откроется мое окно.
Кажется, что ничего не работает. Любые идеи?
Заметьте, я использую шаблон 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>
Ответы
Ответ 1
Вы можете установить положение каретки с помощью свойства CaretIndex
объекта TextBox
. Пожалуйста, имейте в виду, что это не DependencyProperty
. Тем не менее вы все равно можете установить его в XAML следующим образом:
<TextBox Text="123" CaretIndex="{x:Static System:Int32.MaxValue}" />
Не забудьте установить свойство CaretIndex
после Text
, иначе это не сработает. Таким образом, вероятно, это не сработает, если вы привяжетесь к Text
, как в вашем примере. В этом случае просто используйте код таким образом.
NumberOfDigits.CaretIndex = NumberOfDigits.Text.Length;
Ответ 2
Вы также можете создать Поведение, которое, сохраняя при этом код, имеет преимущество в возможности повторного использования.
Пример простого класса поведения с использованием события фокуса текстового поля:
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>
Ответ 3
Если ваше текстовое поле (WinForms) является многострочным с вертикальной полосой прокрутки, вы можете попробовать следующее:
textbox1.Select(textbox1.Text.Length-1, 1);
textbox1.ScrollToCaret();
Примечание. В WPF.ScrollToCaret() не является членом TextBox.
Ответ 4
В случае многострочного курсора установки TextBox
недостаточно.
Попробуйте следующее:
NumberOfDigits.ScrollToEnd();
Ответ 5
Это сработало для меня. Я также использую шаблон MVVM. Тем не менее, моя цель использования MMVM заключается в том, чтобы сделать модульное тестирование возможным и упростить обновление моего интерфейса (слабо связанного). Я не вижу, чтобы я тестировал позицию курсора, поэтому я не против прибегать к коду, стоящему за этой простой задачей.
public ExpeditingLogView()
{
InitializeComponent();
this.Loaded += (sender, args) =>
{
Description.CaretIndex = Description.Text.Length;
Description.ScrollToEnd();
Description.Focus();
};
}