有没有办法在没有子类化Panel并重写OnPaintBackground的情况下禁用面板的擦除?
我试图在没有子类化Panel的情况下实现双缓冲效果。我明白这可能是一个奇怪的事情,但我至少想知道我能不能。以下代码示例说明了这一点:
public partial class Form1 : Form
{
private Bitmap m_image;
public Form1()
{
InitializeComponent();
panel1.Paint += new PaintEventHandler(panel1_Paint);
panel1.MouseMove += new MouseEventHandler(panel1_MouseMove);
m_image = new Bitmap(panel1.Width, panel1.Height);
}
void panel1_MouseMove(object sender, MouseEventArgs e)
{
using (Graphics g = Graphics.FromImage(m_image))
{
g.FillEllipse(Brushes.Black, new Rectangle(e.X, e.Y, 10, 10));
}
panel1.Invalidate();
}
void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(m_image, 0, 0);
}
}
这会导致闪烁,大概是因为它在每个喷漆周期都会擦掉面板。
答案 0 :(得分:4)
你可以破解OnPaintBackground()或者你可以破解WndProc()。要么派生自己的班级。这是微不足道的,我只是不明白你为什么要避免它。远距离拍摄是带有WH_CALLWNDPROC钩子的SetWindowsHookEx(),实在太傻了。
答案 1 :(得分:0)
只需添加:
panel1.BackgroundImage = m_image;
//on panel1_Paint() function.
简单不是吗?
答案 2 :(得分:0)
使用反射来设置受保护的DoubleBuffered属性:
System.Reflection.PropertyInfo aProp =
typeof(System.Windows.Forms.Control).GetProperty(
"DoubleBuffered",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
aProp.SetValue(panel1, true, null);
你也可以通过使变化的区域无效来提高效率(即使没有双缓冲也几乎没有闪烁):
void panel1_MouseMove(object sender, MouseEventArgs e)
{
Rectangle r = new Rectangle(e.X, e.Y, 10, 10);
using (Graphics g = Graphics.FromImage(m_image))
{
g.FillEllipse(Brushes.Black, r);
}
panel1.Invalidate(r);
}