Dan*_*Dan 19
要在调整win表单大小时消除闪烁,请在调整大小时暂停布局.覆盖表单resizebegin/resizeend方法如下.
protected override void OnResizeBegin(EventArgs e) {
SuspendLayout();
base.OnResizeBegin(e);
}
protected override void OnResizeEnd(EventArgs e) {
ResumeLayout();
base.OnResizeEnd(e);
}
Run Code Online (Sandbox Code Playgroud)
这将使控件保持原样(在调整大小之前),并在调整大小操作完成时强制重绘.
Cod*_*ray 17
查看您发布的项目,当您选择第一个选项卡时,使用渐变填充的组框时,闪烁非常糟糕.显示第二个或第三个标签时,几乎没有闪烁,如果有的话.

很明显,问题与您在该标签页上显示的控件有关.快速浏览自定义渐变填充组框类的代码可以提供更具体的原因.每次绘制一个groupbox控件时,你都会做很多非常昂贵的处理.因为每次调整表单大小时每个组框控件都必须重新绘制,所以该代码的执行次数难以置信.
此外,您将控件的背景设置为"透明",必须在WinForms中伪造,方法是让父窗口首先在控件窗口内绘制自己以生成背景像素.然后控制器将自己置于其上.这比使用纯色填充控件的背景更有效SystemColors.Control,并且在组框有机会自己绘制之前,它会让您在调整表单大小时看到正在绘制的表单像素.
这是我从您的自定义渐变填充组框控件类中讨论的特定代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
现在您已经看到了代码,红色警告标志应该会上升.你正在创建一堆 GDI +对象(画笔,笔,区域等),但没有Dispose任何一个!几乎所有代码都应该包含在using语句中.这只是草率的编码.
完成所有这些工作会花费一些成本.当计算机被迫花费大量时间来渲染控件时,其他事情就落后了.你看到一个闪烁,因为它紧张调整以跟上调整大小.它与计算机重载的任何其他东西没有什么不同(比如计算pi的值),当你使用像这里一样多的自定义绘制控件时,这样做真的很容易.Win32中的透明度很难,很多自定义3D绘画也是如此.它使UI看起来和用户感觉笨拙.另一个原因是我不理解本土控制的匆忙.
你真的只有三个选择:
也许对您来说一个好的解决方案是使用Form.ResizeBegin和Form.ResizeEnd事件。
在 ResizeBegin 上将主面板可见性设置为 false,在 ResizeEnd 上将主面板可见性设置为 true。
这样,当有人调整您的表单大小时,面板就不会被重新绘制。