WPF 文本框,更新文本属性重置光标位置

Oli*_*ryn 5 c# wpf

在 WPF 应用程序中,如果以编程方式更新控件Text的属性TextBox,而用户仍然将焦点放在控件上(例如,使用TextChanged或事件),是否可以在属性更新KeyUp后保持用户光标的位置?Text

在正常情况下,如果Text更新属性,并且用户将焦点放在控件上,则光标将简单地重置回TextBox.

Oli*_*ryn 4

是的,可以在值更改后保持用户的光标位置。让我们看一下可以使用它的场景。

考虑一个TextBox控件,您只希望用户输入字母数字值,并删除所有其他字符。

你可能有一些XAML看起来像这样:

<TextBox x:Name="myInput" Margin="72,95,0,0" TextChanged="clearInputHandler" />
Run Code Online (Sandbox Code Playgroud)

...和一个C#处理程序,如下所示:

private void clearInputHandler(object sender, TextChangedEventArgs e) 
{
    string validInput = Regex.Replace(myInput.Text, "[^A-Za-z0-9]", "");
    myInput.Text = validInput;
}
Run Code Online (Sandbox Code Playgroud)

Text但是,这会遇到一个问题:如果更新属性,光标位置将设置为输入的开头。

要解决此问题,请使用该CaretIndex属性,该属性会捕获用户光标的位置:

private void clearInputHandler(object sender, TextChangedEventArgs e) 
{
    int oldIndex = myInput.CaretIndex;
    string oldValue = myInput.Text;
    string validInput = Regex.Replace(myInput.Text, "[^A-Za-z0-9]", "");
    myInput.Text = validInput;

    if (!oldValue.Equals(validInput)) 
    {
        myInput.CaretIndex = oldIndex - 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

关于上述代码示例的一些注释:

  1. 请注意在对属性进行任何更改之前如何CaretIndex收集属性。这样我们就知道在发生任何更改之前光标在哪里。Text
  2. 的原始值TextBox被保存。参见#4。
  3. 在更改用户的光标位置之前Text,会再次设置该属性。
  4. 仅当正则表达式if更改给定的文本时,才会运行底部的语句。当用户键入有效输入时,光标位置本质上会自动前进到下一个空格。但是,如果用户输入无效字符,则会oldIndex注册光标通常应该进入的下一个空格,正则表达式会删除无效字符,并且if运行该语句,并向后移动一个空格,因为无效字符已被删除。