Question

En C # .NET, j'essaie de modifier par programme la couleur de la bordure dans une zone de groupe.

Mise à jour: Cette question a été posée lorsque je travaillais sur un système Winforms avant de passer à .NET.

Était-ce utile?

La solution

Sur la base de la réponse précédente, une meilleure solution comprenant l’étiquette de la zone de groupe:

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

Vous voudrez peut-être ajuster le x / y pour le texte, mais pour mon usage, c'est parfait.

Autres conseils

Ajoutez simplement un événement de peinture.

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

Il suffit de définir l'action de la peinture sur n'importe quel objet (pas seulement les boutons) sur cette méthode pour dessiner une bordure.

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

    }

Il ne sera toujours pas joli et arrondi comme l’original, mais c’est beaucoup plus simple.

FWIW, c’est l’implémentation que j’ai utilisée. C'est un enfant de GroupBox mais il permet de définir non seulement le BorderColor, mais également l'épaisseur du cadre et le rayon des coins arrondis. Vous pouvez également définir le montant de retrait souhaité pour l’étiquette GroupBox et utiliser un retrait négatif du côté droit.

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

Pour que cela fonctionne, vous devez également étendre la classe Graphics de base (Remarque: ceci est dérivé d'un code que j'ai trouvé ici une fois lorsque j'essayais de créer un contrôle Panel aux coins arrondis, mais je ne le trouve pas. le message original à relier ici):

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

Je ne suis pas sûr que cela s'applique à tous les cas, mais grâce à ce fil de discussion, nous avons rapidement intégré l'événement Paint à l'aide d'un programme:

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

Salut!

J'ai réalisé la même frontière avec quelque chose qui pourrait être plus simple à comprendre pour les débutants:

    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. Définissez l'événement Paint sur le contrôle GroupBox. Dans cet exemple, le nom de mon contrôle est "groupSchitaCentru". On a besoin de cet événement à cause de son paramètre e.
  2. Configurez un objet crayon en utilisant la classe System.Drawing.Pen: https://msdn.microsoft.com/en-us/library/f956fzw1 (v = vs.110) .aspx
  3. Définissez les points qui représentent les coins du rectangle représenté par le contrôle. Utilisez la propriété ClientRectangle du contrôle pour obtenir ses dimensions. J'ai utilisé TopLeft (0,7) parce que je veux respecter les limites du contrôle et tracer la ligne autour de son texte. Pour en savoir plus sur le système de coordonnées, consultez la section https. : //docs.microsoft.com/en-us/dotnet/framework/winforms/windows-forms-coordinates

Je ne sais pas, cela peut peut-être aider quelqu'un qui cherche à réaliser cet ajustement à la frontière.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top