关于c#:如何更改组框上边框的颜色?

关于c#:如何更改组框上边框的颜色?

How do you change the color of the border on a group box?

在C#.NET中,我试图以编程方式更改组框中边框的颜色。

更新:在切换到.NET之前,当我在Winforms系统上工作时,曾问过这个问题。


只需添加绘画事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
    private void groupBox1_Paint(object sender, PaintEventArgs e)
    {
        GroupBox box = sender as GroupBox;
        DrawGroupBox(box, e.Graphics, Color.Red, Color.Blue);
    }


    private void DrawGroupBox(GroupBox box, Graphics g, Color textColor, Color borderColor)
    {
        if (box != null)
        {
            Brush textBrush = new SolidBrush(textColor);
            Brush borderBrush = new SolidBrush(borderColor);
            Pen borderPen = new Pen(borderBrush);
            SizeF strSize = g.MeasureString(box.Text, box.Font);
            Rectangle rect = new Rectangle(box.ClientRectangle.X,
                                           box.ClientRectangle.Y + (int)(strSize.Height / 2),
                                           box.ClientRectangle.Width - 1,
                                           box.ClientRectangle.Height - (int)(strSize.Height / 2) - 1);

            // Clear text and border
            g.Clear(this.BackColor);

            // Draw text
            g.DrawString(box.Text, box.Font, textBrush, box.Padding.Left, 0);

            // Drawing Border
            //Left
            g.DrawLine(borderPen, rect.Location, new Point(rect.X, rect.Y + rect.Height));
            //Right
            g.DrawLine(borderPen, new Point(rect.X + rect.Width, rect.Y), new Point(rect.X + rect.Width, rect.Y + rect.Height));
            //Bottom
            g.DrawLine(borderPen, new Point(rect.X, rect.Y + rect.Height), new Point(rect.X + rect.Width, rect.Y + rect.Height));
            //Top1
            g.DrawLine(borderPen, new Point(rect.X, rect.Y), new Point(rect.X + box.Padding.Left, rect.Y));
            //Top2
            g.DrawLine(borderPen, new Point(rect.X + box.Padding.Left + (int)(strSize.Width), rect.Y), new Point(rect.X + rect.Width, rect.Y));
        }
    }


在前面的答案的基础上,一个更好的解决方案包括组框的标签:

1
2
3
4
5
6
7
8
groupBox1.Paint += PaintBorderlessGroupBox;

private void PaintBorderlessGroupBox(object sender, PaintEventArgs p)
{
  GroupBox box = (GroupBox)sender;
  p.Graphics.Clear(SystemColors.Control);
  p.Graphics.DrawString(box.Text, box.Font, Brushes.Black, 0, 0);
}

您可能想要调整文本的x / y,但是对于我来说这是正确的。


只需将任何对象(不仅仅是按钮)上的绘画动作设置为此方法即可绘制边框。

1
2
3
4
5
    private void UserControl1_Paint(object sender, PaintEventArgs e)
    {
        ControlPaint.DrawBorder(e.Graphics, this.ClientRectangle, Color.Red, ButtonBorderStyle.Solid);

    }

它仍然不会像原始的那样漂亮且圆润,但是要简单得多。


FWIW,这是我使用的实现。它是GroupBox的子级,但不仅可以设置BorderColor,还可以设置边框的粗细和圆角的半径。此外,您可以设置所需的GroupBox标签缩进量,并从右侧使用负缩进缩进。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
using System;
using System.Drawing;
using System.Windows.Forms;

namespace BorderedGroupBox
{
    public class BorderedGroupBox : GroupBox
    {
        private Color _borderColor = Color.Black;
        private int _borderWidth = 2;
        private int _borderRadius = 5;
        private int _textIndent = 10;

        public BorderedGroupBox() : base()
        {
            InitializeComponent();
            this.Paint += this.BorderedGroupBox_Paint;
        }

        public BorderedGroupBox(int width, float radius, Color color) : base()
        {
            this._borderWidth = Math.Max(1,width);
            this._borderColor = color;
            this._borderRadius = Math.Max(0,radius);
            InitializeComponent();
            this.Paint += this.BorderedGroupBox_Paint;
        }

        public Color BorderColor
        {
            get => this._borderColor;
            set
            {
                this._borderColor = value;
                DrawGroupBox();
            }
        }

        public int BorderWidth
        {
            get => this._borderWidth;
            set
            {
                if (value > 0)
                {
                    this._borderWidth = Math.Min(value, 10);
                    DrawGroupBox();
                }
            }
        }

        public int BorderRadius
        {
            get => this._borderRadius;
            set
            {   // Setting a radius of 0 produces square corners...
                if (value >= 0)
                {
                    this._borderRadius = value;
                    this.DrawGroupBox();
                }
            }
        }

        public int LabelIndent
        {
            get => this._textIndent;
            set
            {
                this._textIndent = value;
                this.DrawGroupBox();
            }
        }

        private void BorderedGroupBox_Paint(object sender, PaintEventArgs e) =>
            DrawGroupBox(e.Graphics);

        private void DrawGroupBox() =>
            this.DrawGroupBox(this.CreateGraphics());

        private void DrawGroupBox(Graphics g)
        {
            Brush textBrush = new SolidBrush(this.ForeColor);
            SizeF strSize = g.MeasureString(this.Text, this.Font);

            Brush borderBrush = new SolidBrush(this.BorderColor);
            Pen borderPen = new Pen(borderBrush,(float)this._borderWidth);
            Rectangle rect = new Rectangle(this.ClientRectangle.X,
                                            this.ClientRectangle.Y + (int)(strSize.Height / 2),
                                            this.ClientRectangle.Width - 1,
                                            this.ClientRectangle.Height - (int)(strSize.Height / 2) - 1);

            Brush labelBrush = new SolidBrush(this.BackColor);

            // Clear text and border
            g.Clear(this.BackColor);

            // Drawing Border (added"Fix" from Jim Fell, Oct 6, '18)
            int rectX = (0 == this._borderWidth % 2) ? rect.X + this._borderWidth / 2 : rect.X + 1 + this._borderWidth / 2;
            int rectHeight = (0 == this._borderWidth % 2) ? rect.Height - this._borderWidth / 2 : rect.Height - 1 - this._borderWidth / 2;
            // NOTE DIFFERENCE: rectX vs rect.X and rectHeight vs rect.Height
            g.DrawRoundedRectangle(borderPen, rectX, rect.Y, rect.Width, rectHeight, (float)this._borderRadius);

            // Draw text
            if (this.Text.Length > 0)
            {
                // Do some work to ensure we don't put the label outside
                // of the box, regardless of what value is assigned to the Indent:
                int width = (int)rect.Width, posX;
                posX = (this._textIndent < 0) ? Math.Max(0-width,this._textIndent) : Math.Min(width, this._textIndent);
                posX = (posX < 0) ? rect.Width + posX - (int)strSize.Width : posX;
                g.FillRectangle(labelBrush, posX, 0, strSize.Width, strSize.Height);
                g.DrawString(this.Text, this.Font, textBrush, posX, 0);
            }
        }

        #region Component Designer generated code
        /// <summary>Required designer variable.</summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>Clean up any resources being used.</summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
                components.Dispose();

            base.Dispose(disposing);
        }

        /// <summary>Required method for Designer support - Don't modify!</summary>
        private void InitializeComponent() => components = new System.ComponentModel.Container();
        #endregion
    }
}

为了使其工作,您还必须扩展Graphics基础类(注意:这是我尝试创建圆角的Panel控件时在这里找到的一些代码的派生,但是我找不到原始文章链接到这里):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
static class GraphicsExtension
{
    private static GraphicsPath GenerateRoundedRectangle(
        this Graphics graphics,
        RectangleF rectangle,
        float radius)
    {
        float diameter;
        GraphicsPath path = new GraphicsPath();
        if (radius <= 0.0F)
        {
            path.AddRectangle(rectangle);
            path.CloseFigure();
            return path;
        }
        else
        {
            if (radius >= (Math.Min(rectangle.Width, rectangle.Height)) / 2.0)
                return graphics.GenerateCapsule(rectangle);
            diameter = radius * 2.0F;
            SizeF sizeF = new SizeF(diameter, diameter);
            RectangleF arc = new RectangleF(rectangle.Location, sizeF);
            path.AddArc(arc, 180, 90);
            arc.X = rectangle.Right - diameter;
            path.AddArc(arc, 270, 90);
            arc.Y = rectangle.Bottom - diameter;
            path.AddArc(arc, 0, 90);
            arc.X = rectangle.Left;
            path.AddArc(arc, 90, 90);
            path.CloseFigure();
        }
        return path;
    }

    private static GraphicsPath GenerateCapsule(
        this Graphics graphics,
        RectangleF baseRect)
    {
        float diameter;
        RectangleF arc;
        GraphicsPath path = new GraphicsPath();
        try
        {
            if (baseRect.Width > baseRect.Height)
            {
                diameter = baseRect.Height;
                SizeF sizeF = new SizeF(diameter, diameter);
                arc = new RectangleF(baseRect.Location, sizeF);
                path.AddArc(arc, 90, 180);
                arc.X = baseRect.Right - diameter;
                path.AddArc(arc, 270, 180);
            }
            else if (baseRect.Width < baseRect.Height)
            {
                diameter = baseRect.Width;
                SizeF sizeF = new SizeF(diameter, diameter);
                arc = new RectangleF(baseRect.Location, sizeF);
                path.AddArc(arc, 180, 180);
                arc.Y = baseRect.Bottom - diameter;
                path.AddArc(arc, 0, 180);
            }
            else path.AddEllipse(baseRect);
        }
        catch { path.AddEllipse(baseRect); }
        finally { path.CloseFigure(); }
        return path;
    }

    /// <summary>
    /// Draws a rounded rectangle specified by a pair of coordinates, a width, a height and the radius
    /// for the arcs that make the rounded edges.
    /// </summary>
    /// <param name="brush">System.Drawing.Pen that determines the color, width and style of the rectangle.</param>
    /// <param name="x">The x-coordinate of the upper-left corner of the rectangle to draw.</param>
    /// <param name="y">The y-coordinate of the upper-left corner of the rectangle to draw.</param>
    /// <param name="width">Width of the rectangle to draw.</param>
    /// <param name="height">Height of the rectangle to draw.</param>
    /// <param name="radius">The radius of the arc used for the rounded edges.</param>
    public static void DrawRoundedRectangle(
        this Graphics graphics,
        Pen pen,
        float x,
        float y,
        float width,
        float height,
        float radius)
    {
        RectangleF rectangle = new RectangleF(x, y, width, height);
        GraphicsPath path = graphics.GenerateRoundedRectangle(rectangle, radius);
        SmoothingMode old = graphics.SmoothingMode;
        graphics.SmoothingMode = SmoothingMode.AntiAlias;
        graphics.DrawPath(pen, path);
        graphics.SmoothingMode = old;
    }

    /// <summary>
    /// Draws a rounded rectangle specified by a pair of coordinates, a width, a height and the radius
    /// for the arcs that make the rounded edges.
    /// </summary>
    /// <param name="brush">System.Drawing.Pen that determines the color, width and style of the rectangle.</param>
    /// <param name="x">The x-coordinate of the upper-left corner of the rectangle to draw.</param>
    /// <param name="y">The y-coordinate of the upper-left corner of the rectangle to draw.</param>
    /// <param name="width">Width of the rectangle to draw.</param>
    /// <param name="height">Height of the rectangle to draw.</param>
    /// <param name="radius">The radius of the arc used for the rounded edges.</param>

    public static void DrawRoundedRectangle(
        this Graphics graphics,
        Pen pen,
        int x,
        int y,
        int width,
        int height,
        int radius)
    {
        graphics.DrawRoundedRectangle(
            pen,
            Convert.ToSingle(x),
            Convert.ToSingle(y),
            Convert.ToSingle(width),
            Convert.ToSingle(height),
            Convert.ToSingle(radius));
    }
}

对于某些新手来说,我已经达到了相同的边界,而这可能更容易理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
    private void groupSchitaCentru_Paint(object sender, PaintEventArgs e)
    {
        Pen blackPen = new Pen(Color.Black, 2);
        Point pointTopLeft = new Point(0, 7);
        Point pointBottomLeft = new Point(0, groupSchitaCentru.ClientRectangle.Height);
        Point pointTopRight = new Point(groupSchitaCentru.ClientRectangle.Width, 7);
        Point pointBottomRight = new Point(groupSchitaCentru.ClientRectangle.Width, groupSchitaCentru.ClientRectangle.Height);

        e.Graphics.DrawLine(blackPen, pointTopLeft, pointBottomLeft);
        e.Graphics.DrawLine(blackPen, pointTopLeft, pointTopRight);
        e.Graphics.DrawLine(blackPen, pointBottomRight, pointTopRight);
        e.Graphics.DrawLine(blackPen, pointBottomLeft, pointBottomRight);
    }
  • 在GroupBox控件上设置Paint事件。在此示例中,我的控件的名称是" groupSchitaCentru"。由于其参数e,因此需要此事件。
  • 通过使用System.Drawing.Pen类来设置笔对象:https://msdn.microsoft.com/zh-cn/library/f956fzw1(v=vs.110).aspx
  • 设置代表控件所代表矩形的角的点。使用控件的属性ClientRectangle来获取其尺寸。
    我之所以使用TopLeft(0,7),是因为我想尊重控件的边框,并在控件的文本周围画线。
    要获取有关坐标系的更多信息,请点击此处:https://docs.microsoft.com/zh-cn/dotnet/framework/winforms/windows-forms-coordinates
  • 我不知道,这可能会帮助寻求实现此边界调整的人。


    我不确定这是否适用于所有情况,但是由于有了此线程,我们可以使用以下方法以编程方式迅速挂入Paint事件:

    1
    2
    3
    4
    5
    6
    GroupBox box = new GroupBox();
    [...]
    box.Paint += delegate(object o, PaintEventArgs p)
    {
        p.Graphics.Clear(someColorHere);
    };

    干杯!


    推荐阅读

      linux系统查版本命令?

      linux系统查版本命令?,系统,信息,名称,状态,设备,命令,软件,工具,版本,终端,l

      强大系统linux命令?

      强大系统linux命令?,系统,工作,地址,信息,命令,管理,名称,位置,目录,控制台,l

      退出linux系统命令?

      退出linux系统命令?,系统,状态,工作,档案,命令,电脑,工具,基础,信息,时间,lin

      linux系统cmp命令?

      linux系统cmp命令?,系统,工作,标准,信息,命令,一致,目录,指令,功能,文件,请问

      linux系统刷新命令?

      linux系统刷新命令?,系统,工具,情况,最新,单位,工作,管理,信息,软件,服务,Lin

      linux系统sed命令?

      linux系统sed命令?,资料,系统,工作,跨行,代理,时间,简介,命令,文件,都会,Linu

      linux系统维护命令?

      linux系统维护命令?,系统,工作,信息,策略,发展,网络,时间,情况,工具,服务,系

      linux系统安装命令集?

      linux系统安装命令集?,系统,软件,工作,工具,在线,信息,数据,官方网站,基础,

      linux看系统用户命令?

      linux看系统用户命令?,系统,信息,密码,命令,服务,名称,网络,情况,软件,工具,L

      linux系统监听命令?

      linux系统监听命令?,网络,系统,工具,服务,数据,状态,名称,密码,短信,软件,lin

      linux中重启系统命令?

      linux中重启系统命令?,系统,设备,工作,标准,命令,用户,电源,方式,首要,级别,L

      linux新建系统命令?

      linux新建系统命令?,系统,工作,地址,信息,命令,工具,目录,文件,时间,环境,Lin

      linux查看系统盘命令?

      linux查看系统盘命令?,情况,系统,信息,工具,服务,管理,命令,软件,单位,状态,

      linux系统软链接命令?

      linux系统软链接命令?,位置,系统,链接,文件,服务,地址,标准,交通,异常,软件,

      linux登录系统的命令?

      linux登录系统的命令?,系统,工作,地址,名称,网络,密码,信息,服务,软件,资料,l

      linux还原系统命令?

      linux还原系统命令?,系统,数据,设备,工具,电脑,一致,命令,硬盘,文件,备份,lin

      linux系统时钟命令?

      linux系统时钟命令?,时间,系统,命令,信息,城市,网上,资料,时区,终端,时分,lin

      linux系统补全命令?

      linux系统补全命令?,系统,软件,工具,命令,名称,简介,环境,智能,情况,终端,简

      linux系统做镜像命令?

      linux系统做镜像命令?,系统,设备,网上,发行,数据,工具,电脑,信息,代码,软件,L