使用 C# WinForms 我有一个表单,我正在它上面绘制从浅蓝色到深蓝色的渐变背景。我有一些按钮和几个标签,我已经尝试将背景颜色设置为透明,因为我希望背景显示出来 - 特别是对于标签,但这似乎不起作用。
但我注意到,即使代码仅在 form_paint 事件上,绘画也在给标签带来痛苦。
如何使标签不包含相同等级的阴影,而是透明?例如,表单顶部的标签是浅蓝色,而底部的标签是深蓝色。
private void frmOptions_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
Rectangle rectangle = e.ClipRectangle;
using (Brush aBrush = new LinearGradientBrush(rectangle, Color.LightBlue, Color.DarkBlue, LinearGradientMode.Vertical))
{
e.Graphics.FillRectangle(aBrush, rectangle);
}
}
Run Code Online (Sandbox Code Playgroud)
非常感谢您对此的任何帮助。
编辑: 我刚刚逐步调试代码行并注意到正在为表单上的每个对象调用绘制事件 - 标签和按钮,上面第 2 行的矩形具有每次的大小。所以我现在真的很困惑为什么它会被表单上的每个对象调用。
编辑 2:
刚刚逐步完成我的快速测试项目的代码(请参阅下面的评论),并且还注意到正在为每个对象调用 Paint 事件。不同之处在于测试项目没有“ Rectangle rectangle = e.ClipRectangle;”行- 它基本上使用表单的宽度和高度。我上面的代码将矩形设置为 ClipRectangle - 这是每个标签和按钮的大小......这是正常行为吗?如果是这样,那么看起来我需要遵循 Reniuz 下面的答案。
编辑 3
我已将 cliprectangle 线更改为“ Rectangle rectangle = new Rectangle(0, 0, this.Width, this.Height);”,这似乎使透明外观看起来应该如何,但是仍然为表单上的每个对象调用 Paint 事件 - 很好,只有 7 个,所以它正在绘制8 次 :( 认为我仍然会查看“透明标签”代码来测试它。
看看这篇文章。
编辑:
您也可以使用此代码:
public class TransparentLabel : Control
{
public TransparentLabel(Label label)
{
//setting default properties
this.Text = label.Text;
this.Font = label.Font;
this.Location = label.Location;
this.Size = label.Size;
this.Parent = label.Parent;
this.BringToFront();
label.Dispose();
TabStop = false;
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
// do nothing
}
protected override void OnPaint(PaintEventArgs e)
{
DrawText();
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if(m.Msg == 0x000F)
{
DrawText();
}
}
private void DrawText()
{
using(Graphics graphics = CreateGraphics())
using(SolidBrush brush = new SolidBrush(ForeColor))
{
SizeF size = graphics.MeasureString(Text, Font);
// first figure out the top
float top = 0;
switch(textAlign)
{
case ContentAlignment.MiddleLeft:
case ContentAlignment.MiddleCenter:
case ContentAlignment.MiddleRight:
top = (Height - size.Height) / 2;
break;
case ContentAlignment.BottomLeft:
case ContentAlignment.BottomCenter:
case ContentAlignment.BottomRight:
top = Height - size.Height;
break;
}
float left = -1;
switch(textAlign)
{
case ContentAlignment.TopLeft:
case ContentAlignment.MiddleLeft:
case ContentAlignment.BottomLeft:
if(RightToLeft == RightToLeft.Yes)
left = Width - size.Width;
else
left = -1;
break;
case ContentAlignment.TopCenter:
case ContentAlignment.MiddleCenter:
case ContentAlignment.BottomCenter:
left = (Width - size.Width) / 2;
break;
case ContentAlignment.TopRight:
case ContentAlignment.MiddleRight:
case ContentAlignment.BottomRight:
if(RightToLeft == RightToLeft.Yes)
left = -1;
else
left = Width - size.Width;
break;
}
graphics.DrawString(Text, Font, brush, left, top);
}
}
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
RecreateHandle();
}
}
public override RightToLeft RightToLeft
{
get
{
return base.RightToLeft;
}
set
{
base.RightToLeft = value;
RecreateHandle();
}
}
public override Font Font
{
get
{
return base.Font;
}
set
{
base.Font = value;
RecreateHandle();
}
}
private ContentAlignment textAlign = ContentAlignment.TopLeft;
public ContentAlignment TextAlign
{
get { return textAlign; }
set
{
textAlign = value;
RecreateHandle();
}
}
}
Run Code Online (Sandbox Code Playgroud)
透明标签将替换您现有的标签,因此您可以像这样使用它:
TransparentLabel transparentLabel1 = new TransparentLabel(label1);
TransparentLabel transparentLabel2 = new TransparentLabel(label2);
Run Code Online (Sandbox Code Playgroud)
然后你应该看到结果(左边是设计时间,右边是运行时间):
