【问题标题】:Slow Paints On Panel Controls面板控件上的慢速绘制
【发布时间】: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 您想提供您的评论作为答案吗?你说的真的很准确(一如既往)。我最终按照建议自己绘制了控件,它就像一个魅力。
  • 只需告诉我们您在自己的帖子中做了什么并接受它作为答案。

标签: c# vb.net


【解决方案1】:

我在自定义面板中使用 2 个标签和一个图片框来显示文本和图片。正如 cmets 中指出的那样,您可以轻松地自己绘制这些项目(这不仅更快,而且更有意义,因为您必须首先使用控件来处理所有控件 mouseEnter/mouseLeave 事件),从而停止闪烁从发生。

由于我已经创建了用于保存图像和标签文本的属性(与以前的控件一起使用),因此很容易将其转换为自定义面板的绘制事件。

    e.Graphics.DrawString(Me.txtHeaderDescription, New Font("Calibri", 12, FontStyle.Italic), Brushes.White, New Point(105, 15))

    Dim sf As New StringFormat
    sf.Alignment = StringAlignment.Near
    Dim Rectf As RectangleF = New Rectangle(105, 35, 200, 75)
    e.Graphics.DrawString(Me.txtDescription, New Font("Calibri", 8, FontStyle.Regular), Brushes.White, Rectf, sf)

    e.Graphics.DrawImage(Me.MyImage, 5, 3, 96, 96)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 2013-03-18
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多