DigitTextBox (只能输入数字的TextBox)

直接写代码

 

    public class DigitTextBox : TextBox, ISupportInitialize
    {
        [DllImport("user32.dll", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
        [ResourceExposure(ResourceScope.None)]
        public static extern bool MessageBeep(int type);

        private static readonly decimal DefaultValue = decimal.Zero;
        private static readonly decimal DefaultMinimum = decimal.MinValue;
        private static readonly decimal DefaultMaximum = decimal.MaxValue;

        private const bool DefaultHexadecimal = false;
        private const int InvalidValue = -1;

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), Bindable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override string Text
        {
            get => base.Text; set
            {
                base.Text = value;

                ChangingText = false;
                // 通常,“文本已更改”事件处理程序中的代码将“ ChangeingText”设置回false。
                // 如果文本实际上没有更改,则事件处理程序将永远不会触发。
                // 从此属性退出时,ChangeingText应该始终为false。

                if (UserEdit)
                {
                    ValidateEditText();
                }
            }
        }


        /// <summary>
        /// 获取或设置分配给上下控件的值。
        /// </summary>
        [Category(nameof(Appearance)),
        Bindable(true),
        Description("当前值")]
        public decimal Value
        {

            get
            {
                if (UserEdit)
                {
                    ValidateEditText();
                }
                return currentValue;
            }

            set
            {
                if (value != currentValue)
                {

                    if (!initializing && ((value < minimum) || (value > maximum)))
                    {
                        throw new ArgumentOutOfRangeException("Value", $"值必须在{minimum}-{maximum}之间");
                    }
                    else
                    {
                        currentValue = value;

                        OnValueChanged(EventArgs.Empty);
                        currentValueChanged = true;
                        UpdateEditText();
                    }
                }
            }
        }

        public bool userEdit;

        /// <summary>
        /// 获取或设置一个值,该值指示用户是否输入了值。
        /// </summary>
        protected bool UserEdit
        {
            get
            {
                return userEdit;
            }

            set
            {
                userEdit = value;
            }
        }


        //////////////////////////////////////////////////////////////
        // 成员变量
        //////////////////////////////////////////////////////////////

        // 最小值和最大值
        private decimal minimum = DefaultMinimum;
        private decimal maximum = DefaultMaximum;

        // 内部存储当前值
        private decimal currentValue = DefaultValue;
        private bool currentValueChanged;

        public bool ChangingText { get => changingText; private set => changingText = value; }

        // onValueChanged事件的事件处理程序
        private event EventHandler ValueChanged = null;

        // 初始化控件时禁用值范围检查
        private bool initializing = false;

        private bool changingText;

        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            base.OnKeyPress(e);

            NumberFormatInfo numberFormatInfo = System.Globalization.CultureInfo.CurrentCulture.NumberFormat;
            string decimalSeparator = numberFormatInfo.NumberDecimalSeparator;
            string groupSeparator = numberFormatInfo.NumberGroupSeparator;
            string negativeSign = numberFormatInfo.NegativeSign;

            string keyInput = e.KeyChar.ToString();
            if (char.IsDigit(e.KeyChar))
            {
                // 数字
            }
            else
            if ((keyInput.Equals(decimalSeparator) && !Text.Contains(decimalSeparator))
                || (keyInput.Equals(groupSeparator) && !(Text.Length > 0 && Text.LastOrDefault().ToString() == (groupSeparator)))
                || (keyInput.Equals(negativeSign) && !Text.Contains(negativeSign) && SelectionStart == 0))
            {
                // 小数点分隔符/负号
            }
            else if (e.KeyChar == '\b')
            {
                // 退格键
            }
            else if ((ModifierKeys & (Keys.Control | Keys.Alt)) != 0)
            {
                // 让编辑控件处理控件和alt组合键
            }
            else
            {
                // 吃掉这个无效的键并发出哔声
                e.Handled = true;
                MessageBeep(0);
            }

        }

        protected void UpdateEditText()
        {
            // 如果要初始化,我们还不想更新编辑文本,以防万一该值无效。
            if (initializing)
            {
                return;
            }

            // 如果当前值是用户编辑的,则在重新格式化之前解析该值
            if (UserEdit)
            {
                ParseEditText();
            }

            // 尝试设置Value属性之前,请验证用户是否没有以“-”开头的字符串,因为“-”是有效的字符,可用来以该字符开头的字符串代表负数。
            if (currentValueChanged || (!string.IsNullOrEmpty(Text) &&
                !(Text.Length == 1 && Text == "-")))
            {

                currentValueChanged = false;
                ChangingText = true;

                Text = GetNumberText(currentValue);
            }
        }
        private string GetNumberText(decimal num)
        {
            string text;


            text = num.ToString(CultureInfo.CurrentCulture);

            return text;
        }
        protected void ParseEditText()
        {

            try
            {
                // 尝试设置Value属性之前,请验证用户是否没有以“-”开头的字符串,因为“-”是有效的字符,可用来以一个负数开头的字符串。
                if (!string.IsNullOrEmpty(Text) &&
                    !(Text.Length == 1 && Text == "-"))
                {
                    Value = Constrain(decimal.Parse(Text, CultureInfo.CurrentCulture));
                }
            }
            catch
            {
                // Leave value as it is
            }
            finally
            {
                UserEdit = false;
            }
        }
        private decimal Constrain(decimal value)
        {
            if (value < minimum)
            {
                value = minimum;
            }

            if (value > maximum)
            {
                value = maximum;
            }

            return value;
        }

        protected virtual void OnValueChanged(EventArgs e)
        {

            ValueChanged?.Invoke(this, e);
        }

        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);
            OnTextBoxTextChanged(this, e);
        }

        protected virtual void OnTextBoxTextChanged(object source, EventArgs e)
        {
            if (changingText)
            {
                ChangingText = false;
            }
            else
            {
                UserEdit = true;
            }
        }
        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
            if (UserEdit)
            {
                ValidateEditText();
            }
        }

        private void ValidateEditText()
        {
            ParseEditText();
            UpdateEditText();
        }

        public void EndInit()
        {
            initializing = false;
            Value = Constrain(currentValue);
            UpdateEditText();
        }

        public void BeginInit()
        {
            initializing = true;
        }
    }

  

上一篇:mysql-数字类型:自增主键踩坑


下一篇:基本数据类型2(The basic data type )