【问题标题】:How to hide arrows on numericUpDown control in win forms?如何在winforms中隐藏numericUpDown控件上的箭头?
【发布时间】:2015-04-04 19:58:53
【问题描述】:

为了隐藏箭头,我添加了 numericUpDown.Controls[0].Hide();它隐藏了箭头,但在打开表单时会留下空白。

如何将它们隐藏成简单的文本框?

【问题讨论】:

  • 为什么要隐藏它们..?
  • 没有它们更美
  • 我能理解你的目标,它们真的很丑,光标键也可以;但我无法在这里隐藏或删除它们。所以最好的选择是将其放入标签中,从而覆盖裸露的右侧
  • 我只需要表单上的几个数字字段进行一些计算,如果我使用 textBox 我不太确定如何将它们的值转换为双精度值并用它们进行一些计算

标签: c# winforms


【解决方案1】:

您可以通过访问 numericUpDown 的 Controls 属性来隐藏箭头。您可以隐藏或删除它们:

numericUpDown1.Controls[0].Visible = false;

numericUpDown1.Controls.RemoveAt(0);

您可以在 IntializeComponent() 之后立即执行此操作。

【讨论】:

  • 它删除了向上向下按钮,但仍然留下无法使用的白色区域。
【解决方案2】:

此解决方案还删除了未使用的空间:

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

    protected override void OnTextBoxResize(object source, EventArgs e)
    {
        Controls[1].Width = Width - 4;
    }
}

【讨论】:

  • 以防万一有人使用它,如果您不指定边框,则必须添加 4。
【解决方案3】:

NumericUpDown很好,他们免费提供Min, Max and Increment 值并保留doubles

但我能理解你的目标,它们真的很丑,而且没有那些讨厌的小箭头,光标键也能正常工作;但我什至无法在这里隐藏或删除它们。

所以我认为最好的选择是将NUD 放入一个较小的Label 中,从而覆盖它的正确部分..

如果您愿意,可以将以下解决方法封装在 NakedNumericUpDown 类中;-)

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

当然,您可能希望动态创建Label..

一个问题是,现在没有视觉线索表明用户可以向上箭头键更改值,但

【讨论】:

    【解决方案4】:

    添加自定义Paint event 以按照您的方式绘制箭头(或在其上绘制)。

    例如

        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;
                    }
                }
            }
        };
    

    忽略点击事件:

    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);
        }
    }
    

    【讨论】:

    • 要擦除整个按钮,然后使用g.Clear(nud.BackColor); 但是您还应该使用NativeWindow 并覆盖WndProc 方法以忽略HITTEST 消息。否则有可能用户点击了一个按钮并没有意识到它。
    【解决方案5】:

    创建您自己的数字类。数字控件包含 2 个控件。第一个文本框和第二个按钮。隐藏第一个,所有问题都将迎刃而解。

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

    然后从工具箱中获取您的数字控件:MyCustomNumericBox。 或者您可以在构造函数初始化期间删除该控件,仅此而已

         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);
            }
        }
    }
    

    【讨论】:

    • 但是如果未使用的区域仍然显示为表单中的一个洞,那么做这一切有什么意义呢?
    【解决方案6】:

    箭头不就是为什么有人会使用 numericupdown 控件的原因吗? 如果您希望它像文本框,请使用文本框。获取键盘向上或向下箭头按下拦截 keydown 事件的功能。

    【讨论】:

    • 拦截箭头键点击,验证结果。这不是我想要让我的代码膨胀的东西。这些数据属于代码的 UI 部分,而不是逻辑部分。
    • 不,ValueMinimumMaximum 等都是。我也继承了这个东西并添加了一个自定义格式化程序,利用String.Format 添加单位,即“1.23 μW”,以及自定义处理 NaN。当作为indicator继承时,箭头实际上是不合适的。
    【解决方案7】:

    您可以使用此代码。 此代码显示 up&down 控制器,但它们不起作用,您在 Form_Load 中使用此代码

    YourNumericName.Controls[0].Enabled= false;
    

    【讨论】:

      【解决方案8】:

      简单的解决方案:将输入类型从数字更改为电话 输入类型="tel"

      【讨论】:

      • Windows 窗体,而不是 HTML。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-30
      • 2014-07-04
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      • 2017-01-08
      • 1970-01-01
      相关资源
      最近更新 更多