简体   繁体   English

TextChanged事件的奇怪错误(WPF文本框)

[英]Curious bug with TextChanged event (WPF Textbox)

I have a textbox that I'm trying to limit in two ways: 我有一个文本框,我试图以两种方式限制:

1 - I only want to allow numeric values, no decimals 1 - 我只想允许数字值,没有小数

2 - I only want to accept numbers that are <= 35 2 - 我只想接受<= 35的数字

I have the following events to handle this: 我有以下事件来处理这个:

private void TextBoxWorkflowCountPreviewTextInput(object sender, TextCompositionEventArgs e)
{
    if (!IsNumeric(e.Text, NumberStyles.Integer)) e.Handled = true;
}

public bool IsNumeric(string val, NumberStyles numberStyle)
{
    double result;
    return double.TryParse(val, numberStyle, CultureInfo.CurrentCulture, out result);
}

private void TextBoxWorkflowCountTextChanged(object sender, TextChangedEventArgs e)
{
    if (!string.IsNullOrEmpty(textBoxWorkflowCount.Text) && Convert.ToInt32(textBoxWorkflowCount.Text) <= 35) e.Handled = true;
    else
    {
        MessageBox.Show("Must not be higher then 35");
        textBoxWorkflowCount.Text = "35";
    }
}

This on the surface works perfectly fine - except when the user either pastes data into the textbox (appears unavoidable) or even more curiously - if the user enters a number and then hits backspace (making the textbox blank again) the messagebox letting the user know that their value is >35 appears (even though that is definitely not the case). 表面上的这个工作完全正常 - 除非用户将数据粘贴到文本框中(看起来不可避免)或更奇怪 - 如果用户输入数字然后点击退格(使文本框再次空白)消息框让用户知道他们的价值> 35出现(尽管绝对不是这样)。 The first issue I can live with if I have to - but the second is game breaking and after 30 minutes of trying to solve it I've got nowhere. 如果必须的话,我可以忍受的第一个问题 - 但第二个问题是游戏破坏,在尝试解决它的30分钟后我无处可去。 Help! 救命!

Your code is failing the first condition because 您的代码在第一个条件失败,因为

string.IsNullOrEmpty(textBoxWorkflowCount.Text) 

evaluates to true, so it's falling through to the 'else', and displaying the message. 评估为true,因此它会落入'else'并显示消息。

if (string.IsNullOrEmpty(textBoxWorkflowCount.Text) || Convert.ToInt32(textBoxWorkflowCount.Text) <= 35) e.Handled = true; 

should do the trick 应该做的伎俩

couple months ago I wrote a blog post about Behaviors for TextBox (Windows Phone 7.5 platform), and one of these bahaviors was the TextBoxInputRegexFilterBehavior, which allows you to filter input text. 几个月前,我写了一篇关于针对TextBox行为的博客文章(Windows Phone 7.5平台),其中一个行为是TextBoxInputRegexFilterBehavior,它允许您过滤输入文本。 So if you are familar with how Behaviors work you can use this code 因此,如果您熟悉“行为”的工作方式,则可以使用此代码

using System.Text.RegularExpressions;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;

/// <summary>
/// UI behavior for <see cref="TextBox"/> to filter input text with special RegularExpression.
/// </summary>
public class TextBoxInputRegexFilterBehavior : Behavior<TextBox>
{
    private Regex regex;

    private string originalText;
    private int originalSelectionStart;
    private int originalSelectionLength;

    /// <summary>
    /// Gets or sets RegularExpression.
    /// </summary>
    public string RegularExpression 
    {
        get
        {
            return this.regex.ToString();
        } 

        set 
        {
            if (string.IsNullOrEmpty(value))
            {
                this.regex = null;
            }
            else
            {
                this.regex = new Regex(value);
            }
        } 
    }

    /// <inheritdoc/>
    protected override void OnAttached()
    {
        base.OnAttached();

        this.AssociatedObject.TextInputStart += this.AssociatedObjectTextInputStart;
        this.AssociatedObject.TextChanged += this.AssociatedObjectTextChanged;
    }

    /// <inheritdoc/>
    protected override void OnDetaching()
    {
        base.OnDetaching();

        this.AssociatedObject.TextInputStart -= this.AssociatedObjectTextInputStart;
        this.AssociatedObject.TextChanged -= this.AssociatedObjectTextChanged;
    }

    private void AssociatedObjectTextChanged(object sender, TextChangedEventArgs e)
    {
        if (this.originalText != null)
        {
            string text = this.originalText;
            this.originalText = null;
            this.AssociatedObject.Text = text;
            this.AssociatedObject.Select(this.originalSelectionStart, this.originalSelectionLength);
        }
    }

    private void AssociatedObjectTextInputStart(object sender, TextCompositionEventArgs e)
    {
        if (this.regex != null && e.Text != null && !(e.Text.Length == 1 && char.IsControl(e.Text[0])))
        {
            if (!this.regex.IsMatch(e.Text))
            {
                this.originalText = this.AssociatedObject.Text;
                this.originalSelectionStart = this.AssociatedObject.SelectionStart;
                this.originalSelectionLength = this.AssociatedObject.SelectionLength;
            }
        }
    }
}

So, with this behavior you can write simple regex expression which will filter user input, like this RegularExpression="(3[0-5])|([0-2]?[0-9])" 因此,使用此行为,您可以编写简单的正则表达式,它将过滤用户输入,例如RegularExpression =“(3 [0-5])|([0-2]?[0-9])”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM