将插入符号/光标位置设置为字符串值 WPF 文本框的末尾
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2888907/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set the caret/cursor position to the end of the string value WPF textbox
提问by Zamboni
I am try to set the caret/cursor position to the endof 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.
当我第一次打开窗口时,我尝试将插入符号/光标位置设置为WPF 文本框中字符串值的末尾。当我的窗口打开时,我使用 FocusManager 将焦点设置在我的文本框上。
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.
请注意,我使用的是 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>
回答by wpfwannabe
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:
您可以使用 a 的CaretIndex
属性设置插入符号位置TextBox
。请记住,这不是DependencyProperty
. 尽管如此,您仍然可以像这样在 XAML 中设置它:
<TextBox Text="123" CaretIndex="{x:Static System:Int32.MaxValue}" />
Please remember to set CaretIndex
afterText
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.
请记住CaretIndex
在Text
属性之后设置,否则它将不起作用。因此,如果您Text
在示例中绑定到like,它可能无法工作。在这种情况下,只需像这样使用代码隐藏。
NumberOfDigits.CaretIndex = NumberOfDigits.Text.Length;
回答by Louis
You may also create a Behavior, which, while still being code-behind, has the advantage of being reusable.
您还可以创建一个 Behavior,它虽然仍然是代码隐藏的,但具有可重用的优势。
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:
然后,在您的 XAML 中,您附加如下行为:
<TextBox x:Name="MyTextBox" Text="{Binding Value}">
<i:Interaction.Behaviors>
<behaviors:PutCursorAtEndTextBoxBehavior/>
</i:Interaction.Behaviors>
</TextBox>
回答by Michael Ceranski
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.
这对我有用。我也在使用 MVVM 模式。但是,我使用 MMVM 的目的是使单元测试成为可能,并使更新我的 UI(松散耦合)更容易。我没有看到自己对光标的位置进行单元测试,所以我不介意使用背后的代码来完成这个简单的任务。
public ExpeditingLogView()
{
InitializeComponent();
this.Loaded += (sender, args) =>
{
Description.CaretIndex = Description.Text.Length;
Description.ScrollToEnd();
Description.Focus();
};
}
回答by molbalga
If your textbox (WinForms) is multiline with a vertical scrollbar you can try this:
如果您的文本框 (WinForms) 是带有垂直滚动条的多行文本框,您可以尝试以下操作:
textbox1.Select(textbox1.Text.Length-1, 1);
textbox1.ScrollToCaret();
Note: In WPF .ScrollToCaret() is not a member of TextBox.
注意:在 WPF 中 .ScrollToCaret() 不是 TextBox 的成员。
回答by andreikashin
In case of multiline TextBox
setting cursor is not enough.
Try this:
在多行TextBox
设置光标的情况下是不够的。尝试这个:
NumberOfDigits.ScrollToEnd();
回答by Andrey the Autobot
In WPF if line is long enough it is important also to scroll to the end of the line. So i'm using the following lines:
在 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);
but read this caution (for me it's fine - probably already fixed): TextBox ScrollToHorizontalOffset will not scroll after text is long enough
但请阅读此警告(对我来说很好 - 可能已经修复): TextBox ScrollToHorizontalOffset 在文本足够长后不会滚动
回答by Flourick
None of the answers here worked for me. I am using binding for the TextBox and needed to move the caret right after the window poped up. This did it for me:
这里没有一个答案对我有用。我正在为 TextBox 使用绑定,并且需要在窗口弹出后立即移动插入符号。这为我做到了:
public MyWindow()
{
InitializeComponent();
ContentRendered += (sender, args) =>
{
MyTextBox.CaretIndex = MyTextBox.Text.Length;
MyTextBox.ScrollToEnd();
MyTextBox.Focus();
};
}
Similar to Ceranski answer. Instead of adding to the Loaded we add to ContentRendered.
类似于 Ceranski 的回答。我们没有添加到 Loaded,而是添加到 ContentRendered。
回答by Al Banna Techno logy
@Louis solution will not work if textbox
used in template binding or any type of lazy bindings or lazy value assignments
如果textbox
在模板绑定或任何类型的延迟绑定或延迟值分配中使用,@Louis 解决方案将不起作用
So if the textbox
used for example in Datagrid cell as a template that solution will need for tiny modification to work
因此,如果textbox
例如在 Datagrid 单元格中用作模板,该解决方案将需要进行微小的修改才能工作
and that is subscribing to text changed event
那就是订阅文本更改事件
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;
}
}