C# 如何更改组框上边框的颜色?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/76455/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 11:15:05  来源:igfitidea点击:

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

提问by Amy Patterson

In C#.NET I am trying to programmatically change the color of the border in a group box.

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

Update: This question was asked when I was working on a winforms system before we switched to .NET.

更新:在我们切换到 .NET 之前,我在使用 winforms 系统时被问到这个问题。

采纳答案by Mick Bruno

Building on the previous answer, a better solution that includes the label for the group box:

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

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

You might want to adjust the x/y for the text, but for my use this is just right.

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

回答by swajak

I'm not sure this applies to every case, but thanks to this thread, we quickly hooked into the Paint event programmatically using:

我不确定这是否适用于所有情况,但多亏了这个线程,我们使用以下方法以编程方式快速连接到 Paint 事件:

GroupBox box = new GroupBox();
[...]
box.Paint += delegate(object o, PaintEventArgs p)
{
    p.Graphics.Clear(someColorHere);
};

Cheers!

干杯!

回答by Andy

Just set the paint action on any object (not just buttons) to this method to draw a border.

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

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

    }

It still wont be pretty and rounded like the original, but it is much simpler.

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

回答by user1944617

Just add paint event.

只需添加绘画事件。

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

回答by George

I have achieved same border with something which might be simpler to understand for newbies:

我已经实现了与新手可能更容易理解的东西相同的边界:

    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);
    }
  1. Set the Paint event on the GroupBox control. In this example the name of my control is "groupSchitaCentru". One needs this event because of its parameter e.
  2. Set up a pen object by making use of the System.Drawing.Pen class : https://msdn.microsoft.com/en-us/library/f956fzw1(v=vs.110).aspx
  3. Set the points which represent the corners of the rectangle represented by the control. Used the property ClientRectangle of the the control to get its dimensions. I used for TopLeft (0,7) because I want to respect the borders of the control, and draw the line about the its text. To get more information about the coordinates system walk here : https://docs.microsoft.com/en-us/dotnet/framework/winforms/windows-forms-coordinates
  1. 在 GroupBox 控件上设置 Paint 事件。在这个例子中,我的控件名称是“groupSchitaCentru”。需要这个事件是因为它的参数 e。
  2. 通过使用 System.Drawing.Pen 类设置笔对象:https: //msdn.microsoft.com/en-us/library/f956fzw1(v=vs.110) .aspx
  3. 设置表示由控件表示的矩形角的点。使用控件的属性 ClientRectangle 来获取其尺寸。我使用 TopLeft (0,7) 是因为我想尊重控件的边框,并绘制关于其文本的线条。要获取有关坐标系统的更多信息,请访问:https: //docs.microsoft.com/en-us/dotnet/framework/winforms/windows-forms-coordinates

I do not know, may be it helps someone looking to achieve this border adjustment thing.

我不知道,可能它有助于某人实现边界调整的事情。

回答by NetXpert

FWIW, this is the implementation I used. It's a child of GroupBox but allows setting not only the BorderColor, but also the thickness of the border and the radius of the rounded corners. Also, you can set the amount of indent you want for the GroupBox label, and using a negative indent indents from the right side.

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

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

To make it work, you also have to extend the base Graphics class (Note: this is derived from some code I found on here once when I was trying to create a rounded-corners Panel control, but I can't find the original post to link here):

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

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