我正在制作一个程序,其中我有很多面板和面板。
我在这些面板中有一些自定义绘制的控件。
1面板的resize函数包含用于调整该面板中所有控件的大小和位置的代码。
现在,只要我调整程序的大小,这个面板的大小调整就会激活。这会导致此面板中的组件大量闪烁。
所有用户绘制的控件都是双缓冲的。
有人能帮我解决这个问题吗?
发布于 2011-10-14 04:18:01
要在调整win窗体大小时消除闪烁,请在调整大小时挂起布局。如下所示,覆盖表单的resizebegin/ forms _ the方法。
protected override void OnResizeBegin(EventArgs e) {
SuspendLayout();
base.OnResizeBegin(e);
}
protected override void OnResizeEnd(EventArgs e) {
ResumeLayout();
base.OnResizeEnd(e);
}这将使控件保持不变(就像它们在调整大小之前的位置一样),并在调整大小操作完成时强制重绘。
发布于 2011-01-14 22:19:32
看看你发布的项目,当你选择了第一个选项卡,带有渐变填充的组框时,闪烁真的很糟糕。显示第二个或第三个选项卡时,几乎没有任何闪烁。

因此,很明显,问题与您在选项卡页上显示的控件有关。快速浏览一下自定义渐变填充组框类的代码,就会发现更具体的原因。每次绘制一个groupbox控件时,您都要进行大量非常昂贵的处理。因为每个分组框控件在每次调整窗体大小时都必须重新绘制自身,所以该代码被执行的次数令人难以置信。
此外,您还将控件的背景设置为“透明”,这必须在WinForms中通过要求父窗口首先在控件窗口内绘制自己来生成背景像素来伪造。然后,控件将自己绘制在该控件的顶部。这也比用纯色填充控件的背景(如SystemColors.Control )要做更多的工作,而且这会使您在调整窗体大小时看到窗体的像素正在绘制,而分组框还没有机会绘制它们自己。
下面是我从自定义渐变填充的groupbox控件类中讨论的具体代码:
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看起来很笨拙。还有一个我不理解的原因,那就是为什么要急于放弃本机控件。
你真的只有三个选择:
发布于 2011-06-26 02:30:53
我使用这段代码成功地消除了窗体调整大小时的闪烁。谢谢。
VB.NET
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 ClassC#
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();
}
}https://stackoverflow.com/questions/4690426
复制相似问题