代码:
private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(Pens.White,
e.ClipRectangle.Left,
e.ClipRectangle.Top,
e.ClipRectangle.Width - 1,
e.ClipRectangle.Height - 1);
base.OnPaint(e);
}
如何避免闪烁。以上是Panel中panel1_Paint
事件的Paint
方法。感谢。
答案 0 :(得分:3)
某些Windows窗体控件默认情况下不启用双缓冲。我不确定该面板是否是其中之一,但尝试启用它可能会有所不同。
不幸的是Control.DoubleBuffered
是受保护的,因此除非您从控件继承,否则必须使用反射来启用它。
Control ctrl;
ctrl.GetType()
.GetProperty("DoubleBuffered",
BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(control, true, null);
答案 1 :(得分:0)
问题很可能是由于未启用double buffering引起的。 双缓冲是首先写入内部(不可见)缓冲区直到所有绘制操作完成然后将所述缓冲区blit到可见缓冲区的过程,这样可以通过简化实际缓冲区上的绘制操作来避免闪烁。
http://msdn.microsoft.com/en-us/library/3t7htc9c(v=vs.110).aspx列出了可能的解决方案。 将属性DoubleBuffered设置为true似乎是最简单的方法。但是,由于它受到保护,您需要使用反射来访问它或从面板类继承,在新类中将其设置为true并使用所述新类:
public class myPanel : Panel {
public myPanel() : base() {
this.DoubleBuffered = true;
}
}
答案 2 :(得分:0)
有几种方法可以防止容器控件的闪烁,例如面板控件。这些方法中的每一个都涉及派生自 Panel
基类(或其他合适的基类)。
第一种方法是启用双缓冲,可以使用以下代码行完成:
this.DoubleBuffered = true;
第二种有效方法是覆盖CreateParams
属性并启用WS_EX_COMPOSITED
。这是使用以下代码完成的:
private const int WS_EX_COMPOSITED = 0x02000000;
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= WS_EX_COMPOSITED;
return cp;
}
}
为了访问这些属性中的任何一个,我们已经确定,我们需要从基类派生。因此,整个类声明可能如下所示:
public class GraphicsPanel : Panel
{
private const int WS_EX_COMPOSITED = 0x02000000;
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= WS_EX_COMPOSITED;
return cp;
}
}
public GraphicsPanel()
{
this.DoubleBuffered = true;
}
}
在重建我们的解决方案后,将在名为GraphicsPanel
的工具箱中添加一个新控件,我们可以直观地设计它。在运行时,您应该注意到更少的闪烁。