简体   繁体   中英

Change Border Color of NumericUpDown

I am very new to C#, and have a question. I have been able to change the border colors of buttons and such by changing their FlatStyle to "Flat". With the NumericUpDown , I can't change the FlatStyle. I would like to still be able to use the up and down arrows, so just using something else to cover the edges will not work. Here is a simplified version of what I'm doing in my code:

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace bordertest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            BackColor = Color.Black;
            numericUpDown1.BackColor = Color.Red;
        }
    }
}

You can derive from NumericUpDown , add a BorderColor property, override OnPaint and draw border based on the border color.

using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
public class MyNumericUpDown : NumericUpDown
{
    private Color borderColor = Color.Blue;
    [DefaultValue(typeof(Color), "0,0,255")]
    public Color BorderColor
    {
        get { return borderColor; }
        set
        {
            if (borderColor != value)
            {
                borderColor = value;
                Invalidate();
            }
        }
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        if (BorderStyle != BorderStyle.None)
        {
            using (var pen = new Pen(BorderColor, 1))
                e.Graphics.DrawRectangle(pen,
                    ClientRectangle.Left, ClientRectangle.Top,
                    ClientRectangle.Width - 1, ClientRectangle.Height - 1);
        }
    }
}

在此处输入图像描述

Note: Just as a side note, this control raises paint event and if for any reason someone wants to achieve the same behavior without inheritance they can handle the Paint event and draw the border; however as a general solution and a reusable one, a derived control makes more sense.

private void numericUpDown_Paint(object sender, PaintEventArgs e)
{
    var c = (NumericUpDown)sender;
    ControlPaint.DrawBorder(e.Graphics, c.ClientRectangle,
        Color.Red, ButtonBorderStyle.Solid);
    var r = new Rectangle(1, 1, c.Width - 2, c.Height - 2);
    e.Graphics.SetClip(r);
}

FlatNumericUpDown

I've created a FlatNumericUpDown which supports BorderColor and ButtonHighlightColor . You can download or clone it:

在此处输入图像描述

A Custom Control version that overrides WndProc to paint the NumericUpDown (but it can be applied to many other controls) border using the standard ControlPaint rendering features.

This allows to paint a border without much effort (actually, none:) and have multiple styles available out of the box.

The BorderStyle property is shadowed , to return the extended ButtonBorderStyle values, which includes, eg, Dotted and Dashed style besides the default Solid .

A public BorderColor Property is added to the class, it will of course appear in the PropertyGrid; it allows to change the color of the Border.
It defaults to Color.DarkGray , which is similar to SystemColors.ControlDark .
You can use the same Attribute style used by Reza Aghaei to specify the RGB value instead of "DarkGray" , if you want to be precise .


Add this class to the Project, build the Project, find the Custom Control in the ToolBox and drop it on the Form as usual (in case you don't know what to do with it:)

► Note that you can use this same technique to many other standard Controls (including the TextBox Control, which usually doesn't raise Paint events) and to all of your own designed Custom Controls / Components.

This is what it looks like:

NumericUpdown 自定义边框样式 自定义 NumericUpdown PropertyGrid


using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

[DesignerCategory("Code"), ToolboxItem(true)]
public class NumericUpDownEx : NumericUpDown
{
    private const int WM_PAINT = 0x000F;
    private ButtonBorderStyle m_BorderStyle = ButtonBorderStyle.Solid;
    private Color m_BorderColor = Color.DarkGray;

    public NumericUpDownEx() { }

    public new ButtonBorderStyle BorderStyle {
        get => m_BorderStyle;
        set {
            if (m_BorderStyle != value) {
                m_BorderStyle = value;
                Invalidate();
            }
        }
    }

    [DefaultValue(typeof(Color), "DarkGray")]
    public Color BorderColor {
        get => m_BorderColor;
        set {
            if (m_BorderColor != value) {
                m_BorderColor = value;
                Invalidate();
            }
        }
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        switch (m.Msg) {
            case WM_PAINT:
                if (IsHandleCreated) {
                    using (var g = Graphics.FromHwndInternal(this.Handle)) {
                        ControlPaint.DrawBorder(g, ClientRectangle, m_BorderColor, m_BorderStyle);
                    }
                    m.Result = IntPtr.Zero;
                }
                break;
        }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM