将插入符号/光标位置设置为字符串值 WPF 文本框的末尾
Posted
技术标签:
【中文标题】将插入符号/光标位置设置为字符串值 WPF 文本框的末尾【英文标题】:Set the caret/cursor position to the end of the string value WPF textbox 【发布时间】:2011-02-22 18:03:54 【问题描述】:当我第一次打开窗口时,我尝试将插入符号/光标位置设置为 WPF 文本框中字符串值的 end。当我的窗口打开时,我使用 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】:您可以使用TextBox
的CaretIndex
属性设置插入符号位置。请记住,这不是DependencyProperty
。尽管如此,您仍然可以像这样在 XAML 中设置它:
<TextBox Text="123" CaretIndex="x:Static System:Int32.MaxValue" />
请记住设置CaretIndex
after 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】:这对我有用。我也在使用 MVVM 模式。但是,我使用 MMVM 的目的是使单元测试成为可能,并更容易更新我的 UI(松散耦合)。我没有看到自己对光标的位置进行单元测试,所以我不介意为这个简单的任务求助于背后的代码。
public ExpeditingLogView()
InitializeComponent();
this.Loaded += (sender, args) =>
Description.CaretIndex = Description.Text.Length;
Description.ScrollToEnd();
Description.Focus();
;
【讨论】:
【参考方案4】:如果是多行TextBox
设置光标是不够的。
试试这个:
NumberOfDigits.ScrollToEnd();
【讨论】:
仅代码答案不是好的答案,添加几行来解释问题所在以及您的代码修复它的原因【参考方案5】:在 WPF 中,如果行足够长,滚动到行尾也很重要。所以我使用以下几行:
text_Box.Text = text;
text_Box.CaretIndex = text.Length;
text_Box.ScrollToHorizontalOffset(double.MaxValue);
// or you can use this - for me works also
// text_Box.ScrollToHorizontalOffset(text_Box.GetRectFromCharacterIndex(openFileDialog.FileName.Length).Right);
但请阅读此警告(对我来说这很好 - 可能已经修复): TextBox ScrollToHorizontalOffset will not scroll after text is long enough
【讨论】:
【参考方案6】:如果textbox
用于模板绑定或任何类型的惰性绑定或惰性值分配,@Louis 解决方案将不起作用
因此,如果 textbox
在 Datagrid 单元格中用作模板,该解决方案将需要进行微小的修改才能工作
那就是订阅文本更改事件
class PutCursorAtEndTextBoxBehavior : Behavior<UIElement>
private TextBox _textBox;
protected override void OnAttached()
base.OnAttached();
_textBox = AssociatedObject as TextBox;
if (_textBox == null)
return;
_textBox.GotFocus += TextBoxGotFocus;
// to make it work with binding
_textBox.TextChanged += TextBoxGotFocus;
protected override void OnDetaching()
if (_textBox == null)
return;
_textBox.GotFocus -= TextBoxGotFocus;
_textBox.TextChanged -= TextBoxGotFocus;
base.OnDetaching();
private void TextBoxGotFocus(object sender, RoutedEventArgs routedEventArgs)
_textBox.CaretIndex = _textBox.Text.Length;
【讨论】:
【参考方案7】:这里没有一个答案对我有用。我正在为 TextBox 使用绑定,并且需要在窗口弹出后立即移动插入符号。这是为我做的:
public MyWindow()
InitializeComponent();
ContentRendered += (sender, args) =>
MyTextBox.CaretIndex = MyTextBox.Text.Length;
MyTextBox.ScrollToEnd(); // not necessary for single line texts
MyTextBox.Focus();
;
类似于 Ceranski 的回答。我们添加到ContentRendered
,而不是添加到Loaded
事件。
【讨论】:
它对我有用,但MyTextBox.ScrollToEnd()
不是必需的。【参考方案8】:
由于某些原因,我不得不使用:
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
textBox.CaretIndex = textBox.Text.Length;
textBox.ScrollToEnd();
));
【讨论】:
【参考方案9】:试试这个给定的方法:https://docs.microsoft.com/en-us/dotnet/desktop/wpf/controls/position-the-cursor-at-the-beginning-or-end-of-text?view=netframeworkdesktop-4.8
textBox.Select(2,0);
【讨论】:
【参考方案10】:我想创建一个用户控件/视图,其中包含绑定到 ViewModel 的预填充文本框,当控件打开时,焦点会自动设置在文本框和末尾的插入符号位置。这是我让它工作的唯一方法:
public TextBoxDialogView()
InitializeComponent();
TextBox.GotKeyboardFocus += (sender, args) =>
TextBox.CaretIndex = TextBox.Text.Length;
;
_ = TextBox.Focus();
到目前为止似乎工作得很好......
【讨论】:
以上是关于将插入符号/光标位置设置为字符串值 WPF 文本框的末尾的主要内容,如果未能解决你的问题,请参考以下文章
RichTextBox C# 设置插入符号位置 winforms