问题
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;
}
}
}
回答1:
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:
- Repository:r-aghaei/FlatNumericUpDownExample
- Download master.zip
回答2:
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, e.g., 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:
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;
}
}
}
来源:https://stackoverflow.com/questions/65877575/change-border-color-of-numericupdown