首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的WinForms控件闪烁并缓慢调整大小?

为什么我的WinForms控件闪烁并缓慢调整大小?
EN

Stack Overflow用户
提问于 2011-01-14 19:12:24
回答 8查看 35.4K关注 0票数 14

我正在制作一个程序,其中我有很多面板和面板。

我在这些面板中有一些自定义绘制的控件。

1面板的resize函数包含用于调整该面板中所有控件的大小和位置的代码。

现在,只要我调整程序的大小,这个面板的大小调整就会激活。这会导致此面板中的组件大量闪烁。

所有用户绘制的控件都是双缓冲的。

有人能帮我解决这个问题吗?

EN

回答 8

Stack Overflow用户

发布于 2011-10-14 04:18:01

要在调整win窗体大小时消除闪烁,请在调整大小时挂起布局。如下所示,覆盖表单的resizebegin/ forms _ the方法。

代码语言:javascript
复制
protected override void OnResizeBegin(EventArgs e) {
    SuspendLayout();
    base.OnResizeBegin(e);
}
protected override void OnResizeEnd(EventArgs e) {
    ResumeLayout();
    base.OnResizeEnd(e);
}

这将使控件保持不变(就像它们在调整大小之前的位置一样),并在调整大小操作完成时强制重绘。

票数 23
EN

Stack Overflow用户

发布于 2011-01-14 22:19:32

看看你发布的项目,当你选择了第一个选项卡,带有渐变填充的组框时,闪烁真的很糟糕。显示第二个或第三个选项卡时,几乎没有任何闪烁。

因此,很明显,问题与您在选项卡页上显示的控件有关。快速浏览一下自定义渐变填充组框类的代码,就会发现更具体的原因。每次绘制一个groupbox控件时,您都要进行大量非常昂贵的处理。因为每个分组框控件在每次调整窗体大小时都必须重新绘制自身,所以该代码被执行的次数令人难以置信。

此外,您还将控件的背景设置为“透明”,这必须在WinForms中通过要求父窗口首先在控件窗口内绘制自己来生成背景像素来伪造。然后,控件将自己绘制在该控件的顶部。这也比用纯色填充控件的背景(如SystemColors.Control )要做更多的工作,而且这会使您在调整窗体大小时看到窗体的像素正在绘制,而分组框还没有机会绘制它们自己。

下面是我从自定义渐变填充的groupbox控件类中讨论的具体代码:

代码语言:javascript
复制
protected override void OnPaint(PaintEventArgs e)
{
    if (Visible)
    {
        Graphics gr = e.Graphics;
        Rectangle clipRectangle = new Rectangle(new Point(0, 0), this.Size);
        Size tSize = TextRenderer.MeasureText(Text, this.Font);
        Rectangle r1 = new Rectangle(0, (tSize.Height / 2), Width - 2, Height - tSize.Height / 2 - 2);
        Rectangle r2 = new Rectangle(0, 0, Width, Height);
        Rectangle textRect = new Rectangle(6, 0, tSize.Width, tSize.Height);

        GraphicsPath gp = new GraphicsPath();
        gp.AddRectangle(r2);
        gp.AddRectangle(r1);
        gp.FillMode = FillMode.Alternate;

        gr.FillRectangle(new SolidBrush(Parent.BackColor), clipRectangle);

        LinearGradientBrush gradBrush;
        gradBrush = new LinearGradientBrush(clipRectangle, SystemColors.GradientInactiveCaption, SystemColors.InactiveCaptionText, LinearGradientMode.BackwardDiagonal);
        gr.FillPath(gradBrush, RoundedRectangle.Create(r1, 7));

        Pen borderPen = new Pen(BorderColor);
        gr.DrawPath(borderPen, RoundedRectangle.Create(r1, 7));
        gr.FillRectangle(gradBrush, textRect);
        gr.DrawRectangle(borderPen, textRect);
        gr.DrawString(Text, base.Font, new SolidBrush(ForeColor), 6, 0);
    }

}

protected override void OnPaintBackground(PaintEventArgs pevent)
{
    if (this.BackColor == Color.Transparent)
        base.OnPaintBackground(pevent);
}

现在你已经看到了代码,红色的警告信号应该会升起。你正在创建一个Dispose of GDI+对象(画笔,笔,区域,等等),但是不能对其中的任何一个进行!几乎所有的代码都应该包装在using语句中。那只是草率的编码。

做所有这些工作都是有代价的。当计算机被迫将如此多的时间用于渲染控件时,其他事情就会落后。当它紧跟调整大小时,您会看到一个闪烁。它与其他重载计算机的方法没有什么不同(就像计算pi的值一样),当您使用像这里一样多的自定义绘制控件时,就很容易做到这一点。在Win32中透明是很难的,所以很多自定义的3D绘画也是如此。它让用户觉得UI看起来很笨拙。还有一个我不理解的原因,那就是为什么要急于放弃本机控件。

你真的只有三个选择:

  1. 处理闪烁问题。(我同意,这不是一个好的选择。)
  2. 使用不同的控件,比如标准的内置控件。当然,它们可能没有花哨的渐变效果,但如果用户自定义了他们的Windows主题,那就会有一半的时间看起来是坏的。在深灰色的background.
  3. Change上阅读黑色文本也是相当困难的,因为自定义控件中的绘制代码做的工作更少。您也许能够通过一些简单的“优化”,而不会损失任何视觉效果,但我怀疑这是不太可能的。这是速度和美观之间的权衡。什么都不做总是更快。
票数 17
EN

Stack Overflow用户

发布于 2011-06-26 02:30:53

我使用这段代码成功地消除了窗体调整大小时的闪烁。谢谢。

VB.NET

代码语言:javascript
复制
Public Class Form1

Public Sub New()
    Me.SetStyle(ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer Or ControlStyles.AllPaintingInWmPaint Or ControlStyles.SupportsTransparentBackColor, True)
End Sub

Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
    Me.Update()
End Sub

End Class

C#

代码语言:javascript
复制
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        Resize += Form1_Resize;
        this.SetStyle(ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.SupportsTransparentBackColor, true);
    }

    private void Form1_Resize(object sender, System.EventArgs e)
    {
        this.Update();
    }

}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4690426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档