WPF中TextBox只接受正小数. TextBox in WPF accpets positive decimals only.

本文参考了一个只接受正数的文章,可惜我再查不到那篇的地址了。

我不知道是不是就是这个:www.wpfsharp.com/tag/digitbox/,但是我怎么也打不开这个地址。

然后我本来是以为WPF中会有那种上下箭头按按的TextBox然后只接受数字(类似的控件在Qt里面应该有),不过没搜到然后搜到了我上面提到的那篇文章。

一个简单的思想就是对TextBox的文本进行处理,只留下数字以及第一个小数点

private string LeaveOnlyNumbers(String inString)
{
    occur = false;
    StringBuilder ans = new StringBuilder();
    for (int i = 0; i < inString.Length; ++i)
    {
        if (System.Text.RegularExpressions.Regex.IsMatch(inString[i].ToString(), "^[0-9\\.]*$"))
        {
            if (inString[i] == '.')
            {
                if (!occur)
                {
                    occur = true;
                    ans.Append(inString[i]);
                }
            }
            else ans.Append(inString[i]);
        }
    }
    return ans.ToString();
}

上面代码中的occur是一个全局变量,记录是否已经有小数点出现过。

然后重定义TextBox.Text

new public String Text
{
    get
    {
        return base.Text;
    }
    set
    {
        base.Text = LeaveOnlyNumbers(value);
    }
}

并监听TextChanged

public DigitBox()
{
    TextChanged += new TextChangedEventHandler(OnTextChanged);
    KeyDown += new KeyEventHandler(OnKeyDown);
}

protected void OnTextChanged(object sender, TextChangedEventArgs e)
{
    base.Text = LeaveOnlyNumbers(Text);
}

因为TextBox只接受数字和第一个小数点,所以未处理的键盘输入应该不在这层处理,继续按事件流传送,所以我们需要重载KeyDown。值得注意的是,小数点只有在第一次出现的时候才处理,之后出现也应当不处理,所以这里也用到了occur。否则这个TextBox用起来会有一点很不爽,即在出现第二次小数点的时候,TextBox处理了这个事件,但是又得不到显示,于是光标就会移到最前面。

protected void OnKeyDown(object sender, KeyEventArgs e)
{
    e.Handled = !IsNumberKeyOrDot(e.Key) && !IsDelOrBackspaceOrTabKey(e.Key);
}

private bool IsNumberKeyOrDot(Key inKey)
{
    if (!occur)
    {
        if (inKey == Key.Decimal) return true;
        if (inKey == Key.OemPeriod) return true;
    }
    if (inKey < Key.D0 || inKey > Key.D9)
    {
        if (inKey < Key.NumPad0 || inKey > Key.NumPad9)
        {
            return false;
        }
    }
    return true;
}

private bool IsDelOrBackspaceOrTabKey(Key inKey)
{
    return inKey == Key.Delete || inKey == Key.Back || inKey == Key.Tab;
}

因为需求的原因,这个TextBox只接受正的小数,并不接受负数,其实扩展起来也相当容易,只用判断第一个是不是负号或者正号就可以了,之后的正负号输入全都不处理。

 

posted @ 2012-11-05 21:51  cuero  阅读(960)  评论(0编辑  收藏  举报