17

to hide the arrows I have added numericUpDown.Controls[0].Hide(); and it hides the arrows but leaves white space when form is opened.

enter image description here

How to hide them to be like simple textBox?

AYETY
  • 698
  • 4
  • 23
  • 38
  • why do you need to hide them..? – horHAY Apr 04 '15 at 20:10
  • 5
    It's more beautiful without them – AYETY Apr 04 '15 at 20:12
  • 1
    I can understand your aim, they are truely ugly and the cursor key work just as well; but I can't hide or remove them visually here. so the best option will be to put it into a label and thereby cover the right part of the nud – TaW Apr 04 '15 at 20:15
  • 2
    I just need several number fields on form for some calculations, if I use textBox I'm not very sure how to convert their values to doubles and do some calculations with them – AYETY Apr 04 '15 at 20:21
  • Possible duplicate of [C# WinForms numericUpDown control (removing the spin box)](http://stackoverflow.com/questions/6222601/c-sharp-winforms-numericupdown-control-removing-the-spin-box) – Deantwo Apr 24 '17 at 08:40

10 Answers10

17

You can hide the arrows by accessing the numericUpDown's Controls property. You can either hide or remove them:

numericUpDown1.Controls[0].Visible = false;

or

numericUpDown1.Controls.RemoveAt(0);

You can do this right after IntializeComponent().

user3750325
  • 1,502
  • 1
  • 18
  • 37
6

This solution also removes the unused space:

public class MyNumericUpDown : NumericUpDown
{
    public MyNumericUpDown()
    {
        Controls[0].Hide();
    }

    protected override void OnTextBoxResize(object source, EventArgs e)
    {
        Controls[1].Width = Width - 4;
    }
}
KodFun
  • 323
  • 3
  • 8
2

NumericUpDownare nice, they bring Min, Max and Increment values for free and hold doubles.

But I can understand your aim, they are truly ugly and the cursor keys work just as well without those pesky little arrows; but I can't even hide or remove them visually here.

So I think the best option will be to put the NUD into a smaller Label and thereby cover the right part of it..

If you want to you can wrap the following workaround in a NakedNumericUpDown class ;-)

nudLabel.AutoSize = false;
nudLabel.Location = numericUpDown1.Location;
nudLabel.BorderStyle = numericUpDown1.BorderStyle;
numericUpDown1.BorderStyle = BorderStyle.None;
numericUpDown1.Controls.RemoveAt(0);  // optional
numericUpDown1.Parent = nudLabel;
numericUpDown1.Location = Point.Empty;
nudLabel.ClientSize = numericUpDown1.Size;
nudLabel.Width -= 25;  // shrink enough to cover the arrows

You may want to create the Label dynamically, of course..

One problem is that now there is no visual clue that the users can up the arrow keys to change the values, though

TaW
  • 53,122
  • 8
  • 69
  • 111
2

You can use this code. This code show up&down controllers, but they dont work, you use this code in Form_Load

YourNumericName.Controls[0].Enabled= false;
Alenros
  • 816
  • 7
  • 23
morteza
  • 25
  • 2
1

Add a custom Paint event to draw the arrows how you want (or draw over them).

E.g.

    NumericUpDown nud = new NumericUpDown();
    nud.Font = new Font(FontFamily.GenericSansSerif, 20f, FontStyle.Regular);
    bool isSet = false;
    NW nw = null;
    nud.Enabled = false;
    nud.VisibleChanged += delegate {
        // NUD children consist of two child windows:
        // 1) TextBox
        // 2) UpDownBase - which uses user draw
        if (!isSet) {
            foreach (Control c in nud.Controls) {
                if (!(c is TextBox)) {
                    // prevent flicker
                    typeof(Control).InvokeMember("DoubleBuffered", BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, null, c, new object[] { true });
                    c.Paint += (sender,e) => {
                        var g = e.Graphics;
                        int h = c.Height;
                        int w = c.Width;

                        // cover up the default Up/Down arrows:
                        //g.FillRectangle(SystemBrushes.Control, 3, 3, w - 6, h/2 - 6);
                        //g.FillRectangle(SystemBrushes.Control, 3, h/2 + 3, w - 6, h/2 - 6);

                        // or hide the entire control
                        if (nud.Enabled)
                            g.Clear(nud.BackColor);
                        else
                            g.Clear(SystemColors.Control);
                    };

                    nw = new NW(c.Handle);
                    isSet = true;
                }
            }
        }
    };

To ignore click events:

class NW : NativeWindow {

    public NW(IntPtr hwnd) {
        AssignHandle(hwnd);
    }
    const int WM_NCHITTEST = 0x84;
    protected override void WndProc(ref Message m) {
        if (m.Msg == WM_NCHITTEST)
            return;

        base.WndProc(ref m);
    }
}
Loathing
  • 5,109
  • 3
  • 24
  • 35
  • To erase the entire buttons, then use `g.Clear(nud.BackColor);` But then you should also use a `NativeWindow` and override the `WndProc` method to ignore the `HITTEST` message. Otherwise it's possible the user clicks a button and doesn't realize it. – Loathing Apr 04 '15 at 21:48
1

Create your own numeric class. Numeric controls contains 2 controls. First textbox and second buttons. Hide first one and all your problems will be solved.

 public class MyCustomNumericBox : System.Windows.Forms.NumericUpDown
    {
        public MyCustomNumericBox()
        {
           Controls[0].Visible = false;
        }
    }

Then from toolbox get your numerir control: MyCustomNumericBox. Or you can delete that control during constructor init and that's all

     public class MyCustomNumericBox : System.Windows.Forms.NumericUpDown
    {
        public MyCustomNumericBox()
        {
           Controls.Remove(Controls[0]);
        }
    }

Full code to fit your request: 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;
namespace yournamespace
{
    class NumericBx: NumericUpDown
    {
        public NumericBx()
        {
            var ctr = Controls[0];
            this.Controls[0].Visible = false;
            this.Controls[0].Enabled = false;
            this.Controls.Remove(ctr);
            // I have tried to rewrite sizes to hide unused area...but visual studio fails to 
            //show num control. That is why this part is commented 
            //Controls[0].Size = new Size(0, ClientSize.Height);
            //Controls[1].Size = new Size(ClientSize.Width, ClientSize.Height);
        }
    }
}
Jevgenij Kononov
  • 1,210
  • 16
  • 11
  • 1
    But what's the point of doing all this if the unused area is still shown as a hole in the form? – Spero Jul 01 '19 at 19:37
0

Aren't the arrows just the reason why anyone would use numericupdown control? If you want it to be like textbox, then use textbox. Get the functionality for keyboard up or down arrow presses intercepting the keydown event.

Sami
  • 2,050
  • 1
  • 13
  • 25
  • 4
    Intercepting the arrow key hits, validating the result. That's not somethign I want to bloat my code with. This data belongs in the UI part of the code, not in the logical part. – sanderd17 Sep 07 '16 at 13:45
  • 3
    No, `Value`, `Minimum`, `Maximum`, etc. are. I also inherit this thing and add a custom formatter utilizing `String.Format` to add units i.e. "1.23 μW", and custom handling of NaN. When inherited as an *indicator*, the arrows are actually not appropriate. – djv Oct 20 '17 at 16:00
0

It's not the most elegant solution, but you can use a panel in the Form Designer and set the BackColor property to white and cover the arrows.

Of course this creates a white area where the user cannot interact with the control, so I recommend covering the NumericUpDown's borders and drawing a line on the left edge of the panel. (Looks something like this screenshot in the designer).

Then, add a Paint event to the panel:

private void panel1_Paint(object sender, PaintEventArgs e)
{
  using (Pen pen = new Pen(Color.FromArgb(174, 173, 179), 1))
  {
    e.Graphics.DrawLine(pen, 0, 0, 0, panel1.Height);
  }
}
D8A
  • 1
  • 2
0

I know this is an old thread but no one has solved it satisfactorily. And here is mine solution:

  1. Create a new "CustomControl"

  2. Change CustomControl to NumericUpDown

  3. Add an OnResize overridee

    public partial class nNumeric : NumericUpDown
    {
        public nNumeric()
        {
            InitializeComponent();
        }
        protected override void OnResize(EventArgs e)
        {
            var buttons = this.Controls[0];
            var edit = this.Controls[1];
            buttons.Visible = false;
            edit.MinimumSize = new Size( Width - edit.Left*2, 0);
            edit.Width = this.Width;
        }
    }
    
  4. done, simple and effective :)

I hope it will help someone :)

-1

Simple solution:change the input type from number to tel input type="tel"

aminjabari
  • 21
  • 3