问题
I'm using WinForms
. In my form I have a GroupBox
. This is a custom group box. I wanted a transparent background for the groupbox
. I'm having issues creating a transparent background for the groupbox
The problem with this code is i keep on getting an error when i set the group box backcolor
to transparent.
Error: Control does not support transparent background colors.
g.Clear(BackColor = Color.Transparent);
(This is the line that is giving me the problem)
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(BackColor = Color.Transparent);
// 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));
}
}
private void groupBox1_Paint(object sender, PaintEventArgs e)
{
GroupBox box = sender as GroupBox;
DrawGroupBox(box, e.Graphics, Color.Red, Color.Blue);
}
g.Clear(groupBox1.BackColor = Color.Transparent);
If i do this i get:
This example consists of a
Panel
with a dice image inside the panel, and the customGroupbox
.
回答1:
The GroupBox control supports transparent background unless you use System
as FlatStyle
, but for the border color, you need to paint the group box yourself.
You can inherit from GroupBox
and then because GroupBox
supports Transparent
background, so you can simply override the OnPaint and render your group box without doing any thing about background.
Code
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
public class GroupBoxEx : GroupBox
{
private Color borderColor = Color.Black;
[DefaultValue(typeof(Color), "Black")]
public Color BorderColor
{
get { return borderColor; }
set { borderColor = value; this.Invalidate(); }
}
private Color textColor = Color.Black;
[DefaultValue(typeof(Color), "Black")]
public Color TextColor
{
get { return textColor; }
set { textColor = value; this.Invalidate(); }
}
protected override void OnPaint(PaintEventArgs e)
{
GroupBoxState state = base.Enabled ? GroupBoxState.Normal :
GroupBoxState.Disabled;
TextFormatFlags flags = TextFormatFlags.PreserveGraphicsTranslateTransform |
TextFormatFlags.PreserveGraphicsClipping | TextFormatFlags.TextBoxControl |
TextFormatFlags.WordBreak;
Color titleColor = this.TextColor;
if (!this.ShowKeyboardCues)
flags |= TextFormatFlags.HidePrefix;
if (this.RightToLeft == RightToLeft.Yes)
flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right;
if (!this.Enabled)
titleColor = SystemColors.GrayText;
DrawUnthemedGroupBoxWithText(e.Graphics, new Rectangle(0, 0, base.Width,
base.Height), this.Text, this.Font, titleColor, flags, state);
RaisePaintEvent(this, e);
}
private void DrawUnthemedGroupBoxWithText(Graphics g, Rectangle bounds,
string groupBoxText, Font font, Color titleColor,
TextFormatFlags flags, GroupBoxState state)
{
Rectangle rectangle = bounds;
rectangle.Width -= 8;
Size size = TextRenderer.MeasureText(g, groupBoxText, font,
new Size(rectangle.Width, rectangle.Height), flags);
rectangle.Width = size.Width;
rectangle.Height = size.Height;
if ((flags & TextFormatFlags.Right) == TextFormatFlags.Right)
rectangle.X = (bounds.Right - rectangle.Width) - 8;
else
rectangle.X += 8;
TextRenderer.DrawText(g, groupBoxText, font, rectangle, titleColor, flags);
if (rectangle.Width > 0)
rectangle.Inflate(2, 0);
using (var pen = new Pen(this.BorderColor))
{
int num = bounds.Top + (font.Height / 2);
g.DrawLine(pen, bounds.Left, num - 1, bounds.Left, bounds.Height - 2);
g.DrawLine(pen, bounds.Left, bounds.Height - 2, bounds.Width - 1,
bounds.Height - 2);
g.DrawLine(pen, bounds.Left, num - 1, rectangle.X - 3, num - 1);
g.DrawLine(pen, rectangle.X + rectangle.Width + 2, num - 1,
bounds.Width - 2, num - 1);
g.DrawLine(pen, bounds.Width - 2, num - 1, bounds.Width - 2,
bounds.Height - 2);
}
}
}
Screenshot
Some note about the control
- The
GroupBox
control supports transparent background unless you useSystem
asFlatStyle
. - You can also inherit from
Panel
because is is a container control and also supports transparent back color. - If you need to make a custom control that inherits form
Control
to support transparent background, you should addSetStyle(ControlStyles.SupportsTransparentBackColor, true);
in constructor. - Above code is based on drawing code of original
GroupBox
and I made some changes to fit your requirements and also remains like originalGroupBox
. BorderColor
property added to support custom border color.- Using
ForeColor
property ofGroupBox
to render the title of control may be annoying becauseForeColor
is an ambient property and will be inherited by child controls. So I created another property likeTextColor
for this purpose. (Children of group box will use fore color of group box by default, unless you change their fore color property.)
回答2:
Try this tweak:
inside the form's constructor:
this.TransparencyKey = Color.Red;
then in your code:
g.Clear(groupBox1.TransparencyKey = Color.Red);
回答3:
Have you tried SetStyle?
public partial class myGroupBox : GroupBox
{
public TranspBackground()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}
}
来源:https://stackoverflow.com/questions/34562088/custom-groupbox-with-custom-textcolor-bordercolor-and-transparent-backcolor