【发布时间】:2014-03-25 19:22:35
【问题描述】:
我创建了一个自定义类,它使用一个继承的面板、一个图片框和两个标签,它们充当表单上的“图标”,供用户在整个应用程序中单击和导航。我这样做是因为它提供了更好的图形印象,并且比单独的按钮更具可定制性。
我已经包含一个类来从以下代码项目中绘制圆角矩形(它们在面板上绘制以使面板看起来像它具有圆角): http://www.codeproject.com/Articles/5649/Extended-Graphics-An-implementation-of-Rounded-Rec
关于绘画,我已经连接了我的 MouseEnter 和 MouseLeave 事件来切换布尔值,然后调用 me.invalidate() 根据事件设置的布尔值重新绘制面板背景。我的重绘代码如下:
If mouseoverBool Then 'class variable mouseoverBool set by mouseenter/mouseleave to true/false
Dim g As Graphics = e.Graphics
g.SmoothingMode = SmoothingMode.AntiAlias
Dim brush As New LinearGradientBrush(New Point(Me.Width / 2, 0), New Point(Me.Width / 2, Me.Height), Color.LightSteelBlue, Color.LightBlue)
g.FillRoundedRectangle(brush, 0, 0, Me.Width - 1, Me.Height, 10)
g.FillRoundedRectangle(New SolidBrush(Color.FromArgb(100, 118, 173, 218)), 0, 0, Me.Width, Me.Height, 10)
g.DrawRoundedRectangle(New Pen(ControlPaint.Light(SystemColors.InactiveBorder, 0.0F)), 0, 0, Me.Width - 1, Me.Height - 1, 10)
Else
Dim g As Graphics = e.Graphics
g.SmoothingMode = SmoothingMode.AntiAlias
Dim brush As New LinearGradientBrush(New Point(Me.Width / 2, 0), New Point(Me.Width / 2, Me.Height), SystemColors.GradientInactiveCaption, ControlPaint.Dark(SystemColors.GradientActiveCaption, 0.5F))
g.FillRoundedRectangle(brush, 0, 0, Me.Width - 1, Me.Height, 10)
g.FillRoundedRectangle(New SolidBrush(Color.FromArgb(100, 118, 173, 218)), 0, 0, Me.Width, Me.Height, 10)
g.DrawRoundedRectangle(New Pen(ControlPaint.Light(SystemColors.InactiveBorder, 0.0F)), 0, 0, Me.Width - 1, Me.Height - 1, 10)
End If
或者在 C# 中:
if (mouseoverBool) {
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
LinearGradientBrush brush = new LinearGradientBrush(new Point(this.Width / 2, 0), new Point(this.Width / 2, this.Height), Color.LightSteelBlue, Color.LightBlue);
g.FillRoundedRectangle(brush, 0, 0, this.Width - 1, this.Height, 10);
g.FillRoundedRectangle(new SolidBrush(Color.FromArgb(100, 118, 173, 218)), 0, 0, this.Width, this.Height, 10);
g.DrawRoundedRectangle(new Pen(ControlPaint.Light(SystemColors.InactiveBorder, 0f)), 0, 0, this.Width - 1, this.Height - 1, 10);
} else {
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
LinearGradientBrush brush = new LinearGradientBrush(new Point(this.Width / 2, 0), new Point(this.Width / 2, this.Height), SystemColors.GradientInactiveCaption, ControlPaint.Dark(SystemColors.GradientActiveCaption, 0.5f));
g.FillRoundedRectangle(brush, 0, 0, this.Width - 1, this.Height, 10);
g.FillRoundedRectangle(new SolidBrush(Color.FromArgb(100, 118, 173, 218)), 0, 0, this.Width, this.Height, 10);
g.DrawRoundedRectangle(new Pen(ControlPaint.Light(SystemColors.InactiveBorder, 0f)), 0, 0, this.Width - 1, this.Height - 1, 10);
}
出现的问题是面板内的标签和图片框(所有控件都设置为透明背景)在任何自定义“图标”面板首次绘制背景时刷新其背景的速度很慢。面板开始绘制,半秒后,标签和图片框的背景终于更新了。我假设发生这种情况是因为调用 .invalidate() 会强制自定义面板重新绘制,然后是随后的所有控件。我追求的是“无缝”绘制,整个控件一次绘制,包括标签和图片框。我应该如何尝试实现这一目标?
【问题讨论】:
-
很难猜出是什么黑洞吞噬了十亿个 cpu 周期,sn-ps 没用。在工具箱的所有控件中,标签和图片框在浪费小工具列表中名列前茅。通过用 TextRenderer.DrawText() 替换标签和用 Graphics.DrawImage() 替换图片框,您可以获得“无缝”绘画和无问题的透明度。
-
不应该这么慢。如果您想要无缝绘制,您应该自己完成所有的绘制。
-
@HansPassant 您想提供您的评论作为答案吗?你说的真的很准确(一如既往)。我最终按照建议自己绘制了控件,它就像一个魅力。
-
只需告诉我们您在自己的帖子中做了什么并接受它作为答案。