Come si modifica il colore del bordo su una casella di gruppo?

In C #. NET sto provando a cambiare a livello di codice il colore del bordo in una casella di gruppo.

Aggiornamento: questa domanda è stata posta quando stavo lavorando su un sistema winforms prima di passare a .NET.

Basandosi sulla risposta precedente, una soluzione migliore che include l’etichetta per la casella di gruppo:

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

Potresti voler regolare x / y per il testo, ma per il mio uso è giusto.

Basta aggiungere un evento di pittura.

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

Basta impostare l’azione di pittura su qualsiasi object (non solo i pulsanti) su questo metodo per disegnare un bordo.

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

Non sarà ancora bello e arrotondato come l’originale, ma è molto più semplice.

FWIW, questa è l’implementazione che ho usato. È figlio di GroupBox ma consente di impostare non solo BorderColor, ma anche lo spessore del bordo e il raggio degli angoli arrotondati. Inoltre, puoi impostare la quantità di rientro desiderata per l’etichetta GroupBox e utilizzare un rientro con rientro negativo dal lato destro.

 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 /// Required designer variable. private System.ComponentModel.IContainer components = null; /// Clean up any resources being used. /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) components.Dispose(); base.Dispose(disposing); } /// Required method for Designer support - Don't modify! private void InitializeComponent() => components = new System.ComponentModel.Container(); #endregion } } 

Per farlo funzionare, devi anche estendere la class Graphics di base (Nota: questo è derivato da un codice che ho trovato qui una volta mentre stavo cercando di creare un controllo Panel arrotondato, ma non riesco a trovare il post originale per colbind qui):

 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; } ///  /// 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. ///  /// System.Drawing.Pen that determines the color, width and style of the rectangle. /// The x-coordinate of the upper-left corner of the rectangle to draw. /// The y-coordinate of the upper-left corner of the rectangle to draw. /// Width of the rectangle to draw. /// Height of the rectangle to draw. /// The radius of the arc used for the rounded edges. 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; } ///  /// 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. ///  /// System.Drawing.Pen that determines the color, width and style of the rectangle. /// The x-coordinate of the upper-left corner of the rectangle to draw. /// The y-coordinate of the upper-left corner of the rectangle to draw. /// Width of the rectangle to draw. /// Height of the rectangle to draw. /// The radius of the arc used for the rounded edges. 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)); } } 

Non sono sicuro che questo si applichi ad ogni caso, ma grazie a questo thread, ci siamo rapidamente collegati all’evento Paint usando:

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

Saluti!

Ho raggiunto lo stesso confine con qualcosa che potrebbe essere più semplice da capire per i neofiti:

  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. Impostare l’evento Paint sul controllo GroupBox. In questo esempio il nome del mio controllo è “groupSchitaCentru”. Uno ha bisogno di questo evento a causa del suo parametro e.
  2. Impostare un object penna facendo uso della class System.Drawing.Pen: https://msdn.microsoft.com/en-us/library/f956fzw1(v=vs.110).aspx
  3. Imposta i punti che rappresentano gli angoli del rettangolo rappresentato dal controllo. Utilizzato la proprietà ClientRectangle del controllo per ottenere le sue dimensioni. Ho usato per TopLeft (0,7) perché voglio rispettare i bordi del controllo e tracciare la linea del testo. Per ottenere maggiori informazioni sul sistema di coordinate, fai clic qui: https://docs.microsoft.com/en-us/dotnet/framework/winforms/windows-forms-coordinates

Non lo so, potrebbe essere che aiuta qualcuno che sta cercando di ottenere questo aggiustamento alle frontiere.