上下文:
请考虑使用渐变作为背景的一部分来绘制GroupBox
。
示例:
让我们执行以下操作:
class
的{{1}}。
GroupBox
FlatStyle
设置为property
。FlatStyle.System
是override
方法。WndProc
消息,在其中我们绘制渐变。WM_ERASEBKGND
消息,我们将其称为WM_PRINTCLIENT
和DefWndProc
。添加一个return
作为其子Label
。
( Control
的背景必须透明以能够看到其背后的渐变。 Label
。
Text
的{{1}}。class
Label
方法。override
函数以在WndProc
的{{1}}上绘制DrawThemeParentBackground
的背景。< / li>
问题:
根据是否使用临时变量来保存
GroupBox
Label
,最终结果会有所不同,如下面的代码示例和图片所示:
Graphics
运行上述MCVE (情况1)会产生预期的输出,如示例图片所示。
在注释掉标记为 CASE 1 的行并取消注释标记为 CASE 2 的行时,将得到以下不良输出:
问题:
为什么移除临时变量会产生如此巨大的输出?
答案 0 :(得分:1)
出于完整性考虑,将此作为答案发布。
PaintEventArgs
不会呼叫{{1}上的Dispose
} Graphics
。object
WM_PRINTCLIENT
中将DC 重用,该DC发送到{{ 1}}。在Message
WndProc
上手动调用Dispose
确认了这一点。
Graphics
答案 1 :(得分:0)
这一切可以归结为一个简单的派生类,而无需PInvoking吗?
此类从GroupBox
派生,使用CreateParams CreateParams.ExStyle属性将其设置为Transparent,启用对Control.SetStyle()和ControlStyles.SupportsTransparentBackColor
样式的Transparent颜色的支持(通过这种方式,您可以更好地控制LinearGradientBrush的效果,并覆盖OnPaintBackground()方法以执行绘画。
这只是一个基本示例,但可以通过其他任何方式进行调整,并且仍更具便携性。
您可以在其上放置任何控件。
class GradientGroupBox : GroupBox
{
private const int WS_EX_TRANSPARENT = 0x20;
public GradientGroupBox() => this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
Color gradFillTo = Color.FromArgb(200, SystemColors.Window);
Color gradFillFrom = Color.FromArgb(128, this.Parent.BackColor);
using (LinearGradientBrush gradientBrush = new LinearGradientBrush(this.ClientRectangle, gradFillFrom, gradFillTo, LinearGradientMode.Vertical))
{
e.Graphics.FillRectangle(gradientBrush, this.ClientRectangle);
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams parameters = base.CreateParams;
parameters.ExStyle |= WS_EX_TRANSPARENT;
return parameters;
}
}
}