how to restrict contiguous values in NumericUpDown component c#

Darryl Hoar 116 Reputation points
2023-10-12T15:59:51.3266667+00:00

Greetings,

Using Visual Studio 2019. Have created a c# solution using WinForms.

I have a numericUpDown component on Form1. I have set the minimum property to 0 and the maximum property to 127. If I wanted to prevent number 7,11 and 31 from being selected by the user, how do I accomplish this ?

Thanks in advance.

Developer technologies Visual Studio Other
Developer technologies C#
{count} votes

Accepted answer
  1. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2023-10-17T12:09:19.6+00:00

    Here is a custom NumericUpDown

    • Has a list property for disallowed values
    • Prevents copy from Windows Clipboard
    • Several overrides to prevent disallowed values
    • Prevent beep on pressing enter key
    • Property to get decimal Value as int
    • overrides for DownButton and UpButton refinements of KO
    using System.ComponentModel;
    
    namespace TODO;
    
    public class SpecialNumericUpDown : NumericUpDown
    {
        public SpecialNumericUpDown()
        {
            TextAlign = HorizontalAlignment.Right;
            DisallowValues = new List<decimal>();
        }
    
        [Browsable(false)] public int AsInteger => (int)Value;
    
        public delegate void TriggerDelegate();
    
        public event TriggerDelegate TriggerEvent;
        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                e.Handled = true;
                e.SuppressKeyPress = true;
    
                TriggerEvent?.Invoke();
    
                return;
            }
    
            base.OnKeyDown(e);
        }
    
        [Category("Custom")]
        [Description("Values not permitted")]
        public List<decimal> DisallowValues { get; set; }
    
        [Browsable(false)]
        public bool IsValid => DisallowValues.Contains(Value) == false;
    
        protected override void OnKeyUp(KeyEventArgs e)
        {
            if (DisallowValues.Contains(Value))
            {
                Value++;
                return;
            }
    
            base.OnKeyUp(e);
        }
    
        protected override void OnMouseUp(MouseEventArgs mevent)
        {
    
            if (DisallowValues.Contains(Value))
            {
                Value++;
                return;
            }
    
            base.OnMouseUp(mevent);
        }
    
        public override void DownButton()
        {
            base.DownButton();
            if (DisallowValues.Contains(Value))
            {
                Value--;
            }
        }
    
        public override void UpButton()
        {
            base.UpButton();
            if (DisallowValues.Contains(Value))
            {
                Value++;
            }
        }
    
        // code to prevent paste from clipboard
    
        Handler _handler;
        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            _handler = new Handler(Controls[1]);
        }
        protected override void Dispose(bool disposing)
        {
            if (_handler != null)
                _handler.DestroyHandle();
            base.Dispose(disposing);
        }
        private class Handler : NativeWindow
        {
            Control _control;
            public Handler(Control control)
            {
                _control = control;
                AssignHandle(_control.Handle);
            }
            protected override void WndProc(ref Message m)
            {
                if (m.Msg != 0x0302 /*WM_PASTE*/)
                {
                    base.WndProc(ref m);
                }
                else
                {
                    System.Media.SystemSounds.Beep.Play();
                }
            }
        }
    }
    

    Disallow property in form designer

    CustomProperty

    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
    2023-10-12T17:18:31.9333333+00:00

    the easiest to use on change event, and the value is 7,11, or 31 update with the desired value (+1?). you can not do at the keystroke or the user could not enter 110, 112, ...

    0 comments No comments

  2. KOZ6.0 6,655 Reputation points
    2023-10-12T23:10:36.59+00:00

    If you create a new control by inheriting NumericUpdown, you can prevent button selection.

    public class NumericUpDownEx : NumericUpDown
    {
    
        private readonly TextBox textBox;
    
        public NumericUpDownEx() {
            textBox = Controls.Cast<Control>().OfType<TextBox>().FirstOrDefault();
        }
    
        public override void DownButton() {
            base.DownButton();
            switch (Value) {
                case 7:
                case 11:
                case 31:
                    Value--;
                    break;
            }
        }
    
        public override void UpButton() {
            base.UpButton();
            switch (Value) {
                case 7:
                case 11:
                case 31:
                    Value++;
                    break;
            }
        }
    }
    

    Also, when inputting directly into the TextBox part, you can apply restrictions to the TextBox control extracted using the code above.

    https://learn.microsoft.com/en-us/answers/questions/1377768/help-value-of-text-not-updating-on-keypress-event

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.