在不影响光标位置的情况下将 TextBox 输入限制为特定值

Restrict TextBox input upto particular value without disturbing cursor position

我有一个 WPF 应用程序 (MVVM)。我想限制用户在文本框中输入超过特定值的值。 假设该值为 '100' ,则用户不应该输入 101 等。我尝试了以下代码。

XAML:

<TextBox Text="{Binding SearchText}" FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}" Name="SearchTextBox"  TextChanged="TextBox_TextChanged"/>

代码:

 private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        TextBox textBox = sender as TextBox;
        if (textBox != null && !string.IsNullOrEmpty(textBox.Text))
        {
            int searchIndex = 0;
            int count = 100;
            int.TryParse(textBox.Text, out searchIndex);

            if (textBox != null && !string.IsNullOrEmpty(textBox.Text))
            {
                if (searchIndex > Count)
                {
                    textBox.Text = textBox.Text.Substring(0, textBox.Text.Length - 1);
                }
            }
        }
    }

使用此代码,我可以限制用户输入超过特定值的值。但问题是,当我设置 TextBox 的文本时,光标会移动到第一个数字。有解决办法吗?

您可以像这样使用 SelectionStartSelectionLength

if (searchIndex > Count)
{
     textBox.Text = textBox.Text.Substring(0, textBox.Text.Length - 1);
     textBox.SelectionStart = textBox.Text.Length -1;
     textBox.SelectionLength = 0;
}

试试这个:

代码

 private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        TextBox textBox = sender as TextBox;
        if (textBox != null && !string.IsNullOrEmpty(textBox.Text))
        {
            int searchIndex = 0;
            int count = 100;
            int.TryParse(textBox.Text, out searchIndex);

            if (textBox != null && !string.IsNullOrEmpty(textBox.Text))
            {
                if (searchIndex > count)
                {
                    textBox.Text = textBox.Text.Substring(0, textBox.Text.Length - 1);
                    textBox.SelectionStart = textBox.Text.Length;
                    textBox.SelectionLength = 0;
                }
            }
        }
    }

您可以处理 PreviewTextInput 事件并在验证失败时将 TextCompositionEventArgsHandled 属性 设置为 true:

private void SearchTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    TextBox textBox = sender as TextBox;
    if (textBox != null)
    {
        string text = textBox.Text + e.Text;
        if (!string.IsNullOrEmpty(text))
        {
            int searchIndex = 0;
            int count = 100;
            int.TryParse(text, out searchIndex);
            e.Handled = (searchIndex > count);
        }
    }
}

Thanks. You answer has solved my most of the issues. But still if I delete first digit and enter another digit, then the validation fails. Suppose count is 150. I enter 150 & then delete 1 & again enter 1 then textbox will get 501 & validation will fail

嗯,毕竟你应该坚持处理 TextChanged 事件。试试这个:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    TextBox textBox = sender as TextBox;
    if (textBox != null)
    {
        const int count = 100;
        int searchIndex = 0;
        int.TryParse(textBox.Text, out searchIndex);
        if (searchIndex > count)
        {
            var textChange = e.Changes.First();
            if (textChange != null && textChange.AddedLength > 0)
            {
                int caret = textBox.CaretIndex;
                int length = textBox.Text.Length;
                textBox.TextChanged -= TextBox_TextChanged;
                textBox.Text = textBox.Text.Substring(0, textChange.Offset) + textBox.Text.Substring(textChange.Offset + textChange.AddedLength);
                textBox.TextChanged += TextBox_TextChanged;
                textBox.CaretIndex = caret - Math.Abs(textBox.Text.Length - length);
            }
        }
    }
}

One & 。在这两个答案的帮助下,我解决了我的问题。我正在处理两个事件 PreviewKeyDown 和 TextChanged。

代码:

  private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
            TextBox textBox = sender as TextBox;
            int searchIndex = 0;
            int Count = 100;
            int.TryParse(textBox.Text, out searchIndex);
            if (textBox != null && !string.IsNullOrEmpty(textBox.Text))
            {
                if (searchIndex > Count)
                {
                    textBox.Text = OldValue.ToString();
                    textBox.SelectionStart = start;
                 }
             }
      }

public int OldValue = 0;
public int start = 0;


 private void SearchTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        TextBox textBox = sender as TextBox;
        int.TryParse(textBox.Text, out OldValue);
        start = textBox.SelectionStart;
    }

我在 PreviewKeyDown 事件中保存旧值并在 TextChanged 事件中使用它。