当我第一次打开窗口时,我尝试将插入符/光标位置设置为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>
答案 0 :(得分:89)
您可以使用CaretIndex
的{{1}}属性设置插入位置。请记住,这不是TextBox
。不过,你仍然可以像这样在XAML中设置它:
DependencyProperty
请务必在 <TextBox Text="123" CaretIndex="{x:Static System:Int32.MaxValue}" />
财产后设置CaretIndex
,否则无效。因此,如果您绑定到示例中的Text
,它可能无法工作。在这种情况下,只需使用这样的代码隐藏。
Text
答案 1 :(得分:20)
您还可以创建一个行为,虽然仍然是代码隐藏,但具有可重用的优势。
使用文本框焦点事件的简单行为类示例:
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>
答案 2 :(得分:4)
这对我有用。我也在使用MVVM模式。但是,我使用MMVM的目的是使单元测试成为可能,并使我更容易更新我的UI(松散耦合)。我没有看到自己单元测试光标的位置,所以我不介意使用这个简单任务背后的代码。
public ExpeditingLogView()
{
InitializeComponent();
this.Loaded += (sender, args) =>
{
Description.CaretIndex = Description.Text.Length;
Description.ScrollToEnd();
Description.Focus();
};
}
答案 3 :(得分:3)
如果你的文本框(WinForms)是带有垂直滚动条的多行,你可以试试这个:
textbox1.Select(textbox1.Text.Length-1, 1);
textbox1.ScrollToCaret();
注意:在WPF中.ScrollToCaret()不是TextBox的成员。
答案 4 :(得分:1)
如果多行TextBox
设置光标是不够的。
试试这个:
NumberOfDigits.ScrollToEnd();
答案 5 :(得分:1)
在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 :(得分:1)
如果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 :(得分:0)
这里没有答案对我有用。我正在为TextBox使用绑定,并且需要在窗口弹出后立即移动插入符号。这对我有用:
public MyWindow()
{
InitializeComponent();
ContentRendered += (sender, args) =>
{
MyTextBox.CaretIndex = MyTextBox.Text.Length;
MyTextBox.ScrollToEnd();
MyTextBox.Focus();
};
}
类似于Ceranski的答案。除了添加到Loaded之外,我们添加到ContentRendered。
答案 8 :(得分:0)
出于某些原因,我不得不使用:
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
textBox.CaretIndex = textBox.Text.Length;
textBox.ScrollToEnd();
}));
答案 9 :(得分:0)
textBox.Select(2,0);
答案 10 :(得分:0)
我想创建一个用户控件/视图,其中包含一个绑定到 ViewModel 的预填充文本框,当控件打开时,焦点会自动设置在文本框和末尾的插入符号位置上。这是我让它工作的唯一方法:
public TextBoxDialogView()
{
InitializeComponent();
TextBox.GotKeyboardFocus += (sender, args) =>
{
TextBox.CaretIndex = TextBox.Text.Length;
};
_ = TextBox.Focus();
}
到目前为止似乎工作得很好......