C# 中金额文本框,每隔三位以逗号隔开,做金额输入的时候可以用下

一直都是在做java开发,最近刚刚在搞C#,本来想做一个文本框来进行金额与数理的输入,可是很无奈vs没有这个控件

就去微软官网找到了一个类似的控件,不过不能进行负数的输入,也不能进行小数点的动态配置,

经过两天我改成了我想要的样子可以,可是动态设置小数点位数,可以进行负数输入,负数的时候文本显示为红色。效果图如下

代码可以直接拷贝出来就用

 

  


namespace miniShop.custCom
{
    using System;
    using System.Text;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Globalization;
    using System.Diagnostics;


    /// <devdoc>
    ///     DecimalTextBox control definition class. 
    ///     A text box that accepts numeric decimal input only.
    /// </devdoc>
    public class DecimalTextBox : TextBox
    {
        const int WM_COPY = 0x0301,
                    WM_CUT = 0x0300,
                    WM_PASTE = 0x0302,
                    WM_CLEAR = 0x0303,
                    WM_CONTEXTMENU = 0x007B;

        //static NumberFormatInfo nfi = NumberFormatInfo.CurrentInfo;
        public Decimal TextValue;//文本的 Decimal值
        private NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo();
        private System.Drawing.Color _redColor = System.Drawing.Color.Red; //为负数时候的颜色
        private int _intDecimal=2;
        private bool _isNegative=false;
        private int _decimalLength = 15;
        [Category("Categoria"), DefaultValue(2), Browsable(true), Description("小数的位数")]
        public int intDecimal
        {
            get { return _intDecimal; }
            set
            {
                this._intDecimal = value;
                nfi.NumberDecimalDigits = value;
               
                ResetText();
               
            }
           
        }
        [Category("Categoria"), DefaultValue(false), Browsable(true), Description("是否为可以为负数")]

        public bool isNegative
        {
            get { return this._isNegative; }
            set { this._isNegative = value;
            try
            {
                if (isNegative)
                {
                   
                    if (Text.ToString().IndexOf("-") < 0)
                    {
                        base.Text = "-" + base.Text;
                        this.ForeColor = _redColor;
                    }
                }
            }
            catch { }
            }
        }
        [Category("Categoria"), DefaultValue(15), Browsable(true), Description("文本框的文本长度")]
        public int decimalLength
        {
            get { return _decimalLength; }
            set { this._decimalLength = value; }
        }
       
        /// <devdoc>
        ///     Set the initial params.
        /// </devdoc>
        public DecimalTextBox()
        {
          //  nfi.NumberDecimalDigits = intDecimal;
            base.TextAlign = HorizontalAlignment.Right;
            ResetText();
        }
       
       
        /// <devdoc>
        ///     Overridden to validate and format the text.
        /// </devdoc>
        public override string Text
        {
            get
            {
                return base.Text;
               
            }
            set
            {
                if (value != base.Text)
                {
                    SetFormattedText(new StringBuilder(value));
                }

            }
        }
       

        /// <devdoc>
        ///     Overridden to handle unsupported RETURN key.
        /// </devdoc>
        protected override bool IsInputKey(Keys keyData)
        {
            if ((keyData & Keys.KeyCode) == Keys.Return)
            {
                return false;
            }
            return base.IsInputKey(keyData);
        }

        /// <devdoc>
        ///     Overridden to handle supported shortcuts Ctrl-C (Copy All) & Ctrl-D (Delete All).
        /// </devdoc>
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            //
            // The base class should be called first because it implements ShortcutsEnabled,
            // which takes precedence over Ctrl+C
            //
            bool msgProcessed = base.ProcessCmdKey(ref msg, keyData);
           
            if (!msgProcessed)
            {
                if ((int)keyData == (int)Shortcut.CtrlC)
                {
                    WmCopy();
                    msgProcessed = true;
                }
                else if (((int)keyData == (int)Shortcut.CtrlD))
                {
                    ResetText();
                    msgProcessed = true;
                }
                else if (((int)keyData == (int)Shortcut.CtrlX))
                {
                    WmCopy();
                    ResetText();
                    msgProcessed = true;
                }
            }

            return msgProcessed;
        }

        /// <devdoc>
        ///     Set the initial text.
        /// </devdoc>
        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);

            if (this.Visible)
            {
                this.SelectionStart = 1;
                this.SelectionLength = 0;
            }
        }

        /// <devdoc>
        ///     Handle text deletion.
        /// </devdoc>
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            Keys keyCode = e.KeyCode;

            if (this.SelectionLength > 0)
            {
                // For now we don't support replace over selection.
                this.SelectionLength = 0;
            }

            if (keyCode == Keys.Back || keyCode == Keys.Delete)
            {
                e.Handled = true;

                if ((e.Modifiers & Keys.Modifiers) != 0)
                {
                    // Key modifiers not allowed for these keys.
                    return;
                }

                int caretPos = this.SelectionStart;
                StringBuilder txt = new StringBuilder(this.Text);
                int originalTextLength = txt.Length;

                if (originalTextLength - caretPos <= nfi.NumberDecimalDigits) // caret at a decimal location
                {
                    // Corner cases for caret postion.
                    // At the beginning: Del works as normal.  Bck jumps over the decimal separator.
                    // At the end:: Del does nothing.  Bck works as normal.

                    if (caretPos == originalTextLength && keyCode == Keys.Delete)
                    {
                        return;
                    }

                    // On Bck move caret back by one to perform Del.
                    if (keyCode == Keys.Back)
                    {
                        caretPos--;
                    }

                    bool updateCaret = true;

                    if (txt[caretPos] != nfi.NumberDecimalSeparator[0]) // Not at the decimal separator.
                    {
                        txt.Remove(caretPos, 1);
                        updateCaret = SetFormattedText(txt);
                    }

                    if (updateCaret)
                    {
                        this.SelectionStart = caretPos;
                    }
                }
                else // caret at a whole number's location or at the decimal separator's location.
                {
                    // Corner cases for caret postion.
                    // At the beginning: Del should not move the caret (exeption: When first number is zero it should jump it).
                    //                   Bck should do nothing.
                    // At the end: Del jumps over the decimal separator. Bck works as normal.

                    if (txt[caretPos] == nfi.NumberDecimalSeparator[0]) // at the decimal separator location (end).
                    {
                        if (keyCode == Keys.Delete) // Jump caret over the decimal separator.
                        {
                            this.SelectionStart = caretPos + 1;
                            return;
                        }
                    }

                    if (keyCode == Keys.Back)
                    {
                        if (caretPos == 0) // at the beginning of string.
                        {
                            return;
                        }
                        caretPos--; // Get ready for a Del.
                    }

                    // If caret is at a group separator, deleting the separator would not change the text since it would
                    // get formatted the same way.  We need to skip over it.
                    // Del: skip right.  Bck: we alread skip left above.
                    if (txt[caretPos] == nfi.NumberGroupSeparator[0])
                    {
                        if (keyCode == Keys.Delete)
                        {
                            caretPos++;
                        }

                        this.SelectionStart = caretPos;
                        return;
                    }

                    // removing a number.
                    txt.Remove(caretPos, 1);
                    if (SetFormattedText(txt))
                    {

                        // Set new caret location.
                        if (caretPos == 0)
                        {
                            // When first number is 0, Del on it should simply skip over it.
                            if (txt[0] == '0' && keyCode == Keys.Delete)
                            {
                                caretPos++;
                            }
                        }
                        else
                        {
                            // +1 so the caret moves on Delete or stays on BackSpc.
                            caretPos = caretPos - (originalTextLength - txt.Length) + 1;
                        }

                        this.SelectionStart = caretPos;
                    }
                }
            }
        }

        /// <devdoc>
        ///     Handle input filtering and text insertion.
        /// </devdoc>
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            base.OnKeyPress(e);
            e.Handled = true;  // This disables undersired keys. ProcessCmdKey is used to enabled supported shortcuts.

            // Filter allowed input: integers or decimal separator only.
            if (this.Text.Length > decimalLength)
            {
                e.Handled = true;

            }
            else
            {
                //如果是负数并且输入的为负数
                if (this.isNegative && e.KeyChar == '-')
                {
                    if (!(this.isNegative && this.SelectionStart == 0 && this.Text.IndexOf("-") < 0))
                    {
                        return;
                    }
                }
                else
                {

                    if ((!char.IsDigit(e.KeyChar)) && e.KeyChar != nfi.NumberDecimalSeparator[0])
                    {
                        return;
                    }
                }

                int caretPos = this.SelectionStart;
                StringBuilder txt = new StringBuilder(this.Text);

                if (e.KeyChar == nfi.NumberDecimalSeparator[0])
                {
                    // Go to decimal input location.
                    this.SelectionStart = txt.Length - nfi.NumberDecimalDigits;
                    return;
                }

                if (caretPos == txt.Length) // caret at the end of the box
                {
                    // input ignored.
                    return;
                }

                int originalTextLength = txt.Length;

                if (originalTextLength - caretPos <= nfi.NumberDecimalDigits) // caret at decimal location
                {
                    // Replace the current location's value with the input.
                    txt[caretPos] = e.KeyChar;
                    this.Text = txt.ToString();
                    this.SelectionStart = caretPos + 1;
                }
                else // caret at a whole number's location or at the decimal separator's location.
                {
                    // If caret is at pos 0 and the number is zero, we need to move caret so it can be inserted after the 0
                    // and get properly formatted; otherwise, the input would be inserted at zero (effect = multiplied by 10).
                    if (caretPos == 0 && txt[0] == '0')
                    {
                        caretPos++;
                    }

                    // Insert value.
                   
                    if (e.KeyChar == '-'&&txt.ToString().IndexOf("-")<0)
                    {
                        txt.Insert(0, e.KeyChar);
                    }else
                    {
                        txt.Insert(caretPos, e.KeyChar);
                    }
                    if (SetFormattedText(txt))
                    {
                        this.SelectionStart = caretPos + (txt.Length - originalTextLength);
                    }
                }
            }
          
        }

        /// <devdoc>
        ///     Overridden to reset selected text.
        /// </devdoc>
        protected override void OnMouseUp(MouseEventArgs mevent)
        {
            base.OnMouseUp(mevent);
            ResetSelection();
        }

        /// <devdoc>
        ///     Selecting Text is not allowed.
        /// </devdoc>
        private void ResetSelection()
        {
            if (this.SelectionLength > 0)
            {
                this.SelectionLength = 0;
            }
        }

        /// <devdoc>
        /// </devdoc>
        public override void ResetText()
        {
            SetFormattedText(new StringBuilder("0"));
        }


        /// <devdoc>
        ///     Sets the decimal-formatted text into the control's text.
        ///     Returns false if an exception is thrown during text formatting due to overflow or unexpected characters in
        ///     the specified text.
        ///     Methods calling this method should check for the return value before doing further processing.
        ///     The input should contain interger numbers and decimal group separator characters only; it does not expect
        ///     the string to represent a well formatted decimal number.
        /// </devdoc>
        private bool SetFormattedText(StringBuilder txt)
        {
            // Remove group separators to re-format the string.

            String _text = txt.ToString();
           
            txt.Replace(nfi.NumberGroupSeparator, "");

            try
            {
                string _temp = "-";
                if (_text.IndexOf("-") > -1&&this.isNegative)
                {
                    _temp = "-";
                }
                else
                {
                    _temp = "";
                }
                decimal value = decimal.Parse(txt.ToString()); // parse decimal value.
                txt.Length = 0; // clear text.
              
                txt.Append(value.ToString("N", nfi)); // set new text.
                if (_temp == "-" && txt.ToString().IndexOf("-") < 0)
                {
                    base.Text = _temp + txt.ToString(); // set control's text.
                }
                else
                {
                    base.Text = txt.ToString();
                }
                if (Text.ToString().IndexOf("-") < 0)
                {
                    //isNegative = false;
                    this.ForeColor = System.Drawing.SystemColors.WindowText;
                }
                else
                {
                    this.ForeColor = _redColor;
                }

                TextValue = Decimal.Parse(Decimal.Parse(this.Text).ToString(nfi));
               
               
                return true;
            }
            catch (System.OverflowException)
            {
                // Input too big.
            }
            catch (System.FormatException)
            {
               // Debug.Fail("Input was not in a correct format.");
                // Input not formatted properly.
            }

            return false;
        }

        /// <devdoc>
        ///     Copies current selection text to the clipboard, formatted according to the IncludeLiterals properties but
        ///     ignoring the prompt character.
        ///     Returns true if the operation succeeded, false otherwise.
        /// </devdoc>
        private bool WmCopy()
        {
            try
            {
                Clipboard.SetText(this.Text);
            }
            catch (Exception ex)
            {
                // Note: Sometimes the above operation throws but it successfully sets the
                // data in the clipboard. This usually happens when the Application's Main
                // is not attributed with [STAThread].
                if ( ex is OutOfMemoryException || ex is StackOverflowException)
                {
                    throw;
                }
            }
            return true;
        }

        /// <devdoc>
        /// </devdoc>
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                // Disabled operations.
                case WM_CONTEXTMENU:
                case WM_PASTE:
                    // Do nothing.
                    break;

                case WM_COPY:
                    WmCopy();
                    break;

                case WM_CUT:
                    WmCopy();
                    ResetText();
                    break;

                default:
                    base.WndProc(ref m);
                    break;
            }
        }


        /// Unsupported methods /

        /// <devdoc>
        ///     Unsupported method/property.
        /// </devdoc>
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new bool AcceptsReturn
        {
            get { return false; }
            set { }
        }

        /// <devdoc>
        ///     Unsupported method/property.
        /// </devdoc>
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new bool AcceptsTab
        {
            get { return false; }
            set { }
        }

        /// <devdoc>
        ///     Unsupported method/property.
        /// </devdoc>
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new event EventHandler AcceptsTabChanged
        {
            add { }
            remove { }
        }

        /// <devdoc>
        ///     Unsupported method/property.
        /// </devdoc>
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new AutoCompleteMode AutoCompleteMode
        {
            get { return AutoCompleteMode.None; }
            set { }
        }

        /// <devdoc>
        ///     Unsupported method/property.
        /// </devdoc>
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new AutoCompleteSource AutoCompleteSource
        {
            get { return AutoCompleteSource.None; }
            set { }
        }

        /// <devdoc>
        ///     Unsupported method/property.
        ///     virtual method.
        /// </devdoc>
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public override int MaxLength
        {
            get { return base.MaxLength; }
            set { }
        }

        /// <devdoc>
        ///     Unsupported method/property.
        ///     virtual method.
        /// </devdoc>
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public override bool Multiline
        {
            get { return false; }
            set { }
        }

        /// <devdoc>
        ///     Unsupported method/property.
        /// </devdoc>
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new event EventHandler MultilineChanged
        {
            add { }
            remove { }
        }

        /// <devdoc>
        ///     Unsupported method/property.
        ///     virtual method.
        /// </devdoc>
        [
        EditorBrowsable(EditorBrowsableState.Never)
        ]
        protected override void OnMultilineChanged(EventArgs e)
        {
        }

        /// <devdoc>
        ///     Unsupported method/property.
        /// </devdoc>
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new char PasswordChar
        {
            get { return '\0'; }
            set { }
        }

        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public  new ScrollBars ScrollBars
        {
            get { return ScrollBars.None; }
            set { }
        }


        /// <devdoc>
        ///     Unsupported method/property.
        /// </devdoc>
        [
        EditorBrowsable(EditorBrowsableState.Never)
        ]
        public new void ScrollToCaret()
        {
        }

        /// <devdoc>
        ///     Unsupported method/property.
        /// </devdoc>
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new HorizontalAlignment TextAlign
        {
            get { return base.TextAlign; }
            set { }
        }

        /// <devdoc>
        ///     Unsupported method/property.
        /// </devdoc>
        [
        EditorBrowsable(EditorBrowsableState.Never)
        ]
        public new event EventHandler TextAlignChanged
        {
            add
            {
            }
            remove
            {
            }
        }

        /// <devdoc>
        ///     Unsupported method/property.
        /// </devdoc>
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new bool UseSystemPasswordChar
        {
            get { return false; }
            set { }
        }

        /// <devdoc>
        ///     Unsupported method/property.
        /// </devdoc>
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new bool WordWrap
        {
            get { return false; }
            set { }
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值