Jump to content

NumericUpDown code


midora

Recommended Posts

Here a little bit code which may be used to add funtionality to the NumericUpDown Controls:

Unit specifier, Wraping modes (which is usefull for angle stuff) and increment lists.

I used it for this:

 

post-79572-0-98407400-1361646996_thumb.j

 

using System;
using System.Globalization; // CulturInfo
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace ControlExtensions
{

    public enum WrapMode
    {
        None,
        UseOpposite,
        UseIncrement
    }

    public sealed class ControlNumericUpDown
        : NumericUpDown
    {

        // ----------------------------------------------------------------------
        /// <summary>
        /// Gets or sets wraping behaviour if Value reaches Minimum or Maximum
        /// </summary>
        public WrapMode Wrap
        {
            get { return _wrap; }
            set { _wrap = value;}
        }
        private WrapMode _wrap = WrapMode.None;

        // ----------------------------------------------------------------------
        /// <summary>
        /// Gets or sets a list of values to be used by the up and down buttons
        /// </summary>
        public double[] UpDownList
        {
            get { return _upDownList; }
            set {
                for (int i = value.Length - 1; i > 0; i--)
                {
                    if (value[i] <= value[i - 1])
                        throw new ArgumentException("UpDownList must be ordered from low to high value");
                }
                if ((value[0] < (double)Minimum) || (value[value.Length - 1] > (double)Maximum))
                    throw new ArgumentException(String.Format("UpDownList out of range [{0} {1}]", Minimum, Maximum));
                _upDownList = value;
            }
        }
        private double[] _upDownList = null;

        // ----------------------------------------------------------------------
        /// <summary>
        /// UpButton which supports wrapping
        /// </summary>
        public override void UpButton()
        {
            if (UserEdit)
            {
                ParseEditText();    // finish user edit
            }

            try // Operations on Decimals can throw OverflowException.
            {
                switch (_wrap)
                {
                    case WrapMode.None:
                        if ((_upDownList != null) && (_upDownList.Length > 0))
                        {
                            int i;
                            for (i = 0; i < _upDownList.Length; i++)
                            {
                                if ((double)Value < _upDownList[i]) break;
                            }
                            i = (i >= _upDownList.Length) ? _upDownList.Length - 1 : i;
                            Value = (decimal)_upDownList[i];
                            return;
                        }
                       break;
                    case WrapMode.UseOpposite:
                        if (Value + Increment > Maximum)
                        {
                            Value = Minimum;
                            return;
                        }
                        break;
                    case WrapMode.UseIncrement:
                        if (Value + Increment > Maximum)
                        {
                            Value = Minimum + (Value + Increment - Maximum);
                            return;
                        }
                        break;
                }
            }
            catch (OverflowException)
            {
                Value = Maximum;
                return;
            }
            base.UpButton();
        }

        // ----------------------------------------------------------------------
        /// <summary>
        /// DownButton which supports wrapping
        /// </summary>
        public override void DownButton()
        {
            if (UserEdit)
            {
                ParseEditText();    // finish user edit
            }

            try // Operations on Decimals can throw OverflowException.
            {
                switch (_wrap)
                {
                    case WrapMode.None:
                        if ((_upDownList != null) && (_upDownList.Length > 0))
                        {
                            int i;
                            for (i = _upDownList.Length - 1; i >= 0; i--)
                            {
                                if ((double)Value > _upDownList[i]) break;
                            }
                            i = (i < 0) ? 0 : i;
                            Value = (decimal)_upDownList[i];
                            return;
                         }
                         break;
                    case WrapMode.UseOpposite:
                        if (Value - Increment < Minimum)
                        {
                            Value = Maximum;
                            return;
                        }
                        break;
                    case WrapMode.UseIncrement:
                        if (Value - Increment < Minimum)
                        {
                            Value = Maximum + (Value - Increment - Minimum);
                            return;
                        }
                        break;
                }
            }
            catch (OverflowException)
            {
                Value = Minimum;
                return;
            }
            base.DownButton();
        }


        // ----------------------------------------------------------------------
        /// <summary>
        /// OnEnter select the whole text without the unit
        /// </summary>
        protected override void OnEnter(EventArgs e)
        {
            Select(0, TextWithoutUnit().Length);
            base.OnEnter(e);
        }


        // ----------------------------------------------------------------------
        /// <summary>
        /// Gets or sets the unit string of the numericupdown control
        /// </summary>
        public String Unit
        {
            get { return _unit; }
            set
            {
                _unit = (value == null) ? null : String.Copy(value);
                UpdateEditText();
            }            
        }
        private String _unit;

        // ----------------------------------------------------------------------
        /// <summary>
        /// Catches the value in the minimum to maximum range
        /// </summary>
        private Decimal Constrain(Decimal value)
        {
            if (value < Minimum) return Minimum;
            if (value > Maximum) return Maximum;
            return value;
        }

        // ----------------------------------------------------------------------
        /// <summary>
        /// Returns the text w/o the unit suffix
        /// </summary>
        private String TextWithoutUnit()
        {
            if (string.IsNullOrEmpty(Text)) return String.Empty;
            String text = String.Copy(Text).Trim();
            if (!string.IsNullOrEmpty(Unit))
            {
                if (text.EndsWith(Unit))
                {
                    text = text.Remove(text.Length - Unit.Length);
                    text = text.Trim();
                }
            }
            return text;
        }

        // ----------------------------------------------------------------------
        /// <summary>
        /// Converts number to a text
        /// </summary>
        private string GetNumberText(decimal num)
        {
            string text;

            if (Hexadecimal)
            {
                text = ((Int64)num).ToString("X", CultureInfo.InvariantCulture);
            }
            else
            {
                text = num.ToString((ThousandsSeparator ? "N" : "F") + DecimalPlaces.ToString(CultureInfo.CurrentCulture), CultureInfo.CurrentCulture);
            }
            return text;
        }

        // ----------------------------------------------------------------------
        /// <summary>
        /// Converts 'Text' member to 'Value' member
        /// </summary>
        private new void ParseEditText()
        {
            String numericText = TextWithoutUnit();
            try
            {
                // VSWhidbey 173332: Verify that the user is not starting the string with a "-"
                // before attempting to set the Value property since a "-" is a valid character with
                // which to start a string representing a negative number.
                if (!string.IsNullOrEmpty(numericText) &&
                    !(numericText.Length == 1 && numericText == "-"))
                {
                    if (Hexadecimal)
                    {
                        Value = Constrain(Convert.ToDecimal(Convert.ToInt32(numericText, 16)));
                    }
                    else
                    {
                        Value = Constrain(Decimal.Parse(numericText, CultureInfo.CurrentCulture));
                    }
                }
            }
            catch
            {
                // Leave value as it is
            }
            finally
            {
                UserEdit = false;
            }
        }

        // ----------------------------------------------------------------------
        /// <summary>
        /// Converts 'Value' member to 'Text' member.
        /// If the user just edited the text then the text will be parsed.
        /// </summary>
        protected override void UpdateEditText()
        {
            if (UserEdit)
            {
                ParseEditText();    // finish user edit
            }

            ChangingText = true;
            String text = GetNumberText(Value);
            if (Unit == null)
            {
                Text = text;
            }
            else
            {
                Text = text + " " + Unit;
            }
        }

        // ----------------------------------------------------------------------
        /// <summary>
        /// Converts 'Text' member to 'Value' member and back to 'Text' member
        /// </summary>
        protected override void ValidateEditText()
        {
            // Remark: Same as base function but calls local ParseEditText
            ParseEditText();
            UpdateEditText();
        }

    }
}


 

 

 

midoras signature.gif

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...