I am try to set the caret/cursor position to the end of the string value in my WPF textbox when I open my window for the first time. I use the FocusManager to set the focus on my textbox when my window opens.
Nothing seems to work. Any ideas?
Note, I am using the MVVM pattern, and I included only a portion of the XAML from my 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>
You can set the caret position using CaretIndex
property of a TextBox
. Please bear in mind that this is not a DependencyProperty
. Nevertheless, you may still set it in XAML like this:
<TextBox Text="123" CaretIndex="{x:Static System:Int32.MaxValue}" />
Please remember to set CaretIndex
after Text
property or else it will not work. Thus it probably won't work if you bind to Text
like in your example. In that case, simply use code-behind like this.
NumberOfDigits.CaretIndex = NumberOfDigits.Text.Length;
You may also create a Behavior, which, while still being code-behind, has the advantage of being reusable.
Example of a simple behavior class, using the focus event of the textbox:
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;
}
}
Then, in your XAML, you attach the behavior like so:
<TextBox x:Name="MyTextBox" Text="{Binding Value}">
<i:Interaction.Behaviors>
<behaviors:PutCursorAtEndTextBoxBehavior/>
</i:Interaction.Behaviors>
</TextBox>
This worked for me. I am also using the MVVM pattern. However, my purpose for using a MMVM is to make unit testing possible and to make it easier to update my UI (loosely coupled). I don't see myself unit testing the position of the cursor so I don't mind resorting to the code behind for this simple task.
public ExpeditingLogView()
{
InitializeComponent();
this.Loaded += (sender, args) =>
{
Description.CaretIndex = Description.Text.Length;
Description.ScrollToEnd();
Description.Focus();
};
}
If your textbox (WinForms) is multiline with a vertical scrollbar you can try this:
textbox1.Select(textbox1.Text.Length-1, 1);
textbox1.ScrollToCaret();
Note: In WPF .ScrollToCaret() is not a member of TextBox.
In case of multiline TextBox
setting cursor is not enough.
Try this:
NumberOfDigits.ScrollToEnd();
来源:https://stackoverflow.com/questions/2888907/set-the-caret-cursor-position-to-the-end-of-the-string-value-wpf-textbox