禁用 OnPaintBackground 而不对面板进行子类化?

发布于 2024-09-24 12:12:56 字数 880 浏览 1 评论 0原文

有没有办法在不子类化Panel 和重写OnPaintBackground 的情况下禁用面板的擦除?

我试图在不子类化面板的情况下实现双缓冲效果。我知道尝试这样做可能是一件奇怪的事情,但我至少想知道我是否可以。以下代码示例说明了这一点:

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);
    }
}

这会导致闪烁,可能是因为它在每个绘制周期都会擦除面板。

Is there any way to disable the erasing of a panel without subclassing Panel and overriding OnPaintBackground?

I am trying to achieve a double buffering effect without subclassing Panel. I understand that this may be a weird thing to try to do, but I'd at least like to know if I can or not. The following code sample illustrates this:

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);
    }
}

This causes a flickering, presumably because it is erasing the panel at each paint cycle.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

从来不烧饼 2024-10-01 12:12:56

您可以破解 OnPaintBackground() 或破解 WndProc()。两者都需要派生您自己的类。这很微不足道,我只是不明白你为什么要避免它。长距离镜头是带有 WH_CALLWNDPROC 钩子的 SetWindowsHookEx(),真的太傻了。

You can hack OnPaintBackground() or you can hack WndProc(). Either requires deriving your own class. It's trivial, I just don't see why you'd avoid it. The long distance shot is SetWindowsHookEx() with a WH_CALLWNDPROC hook, too silly really.

赤濁 2024-10-01 12:12:56

只需添加:

panel1.BackgroundImage = m_image;
//on panel1_Paint() function.

简单不是吗?

Just add:

panel1.BackgroundImage = m_image;
//on panel1_Paint() function.

Simple isn't it?

怪我鬧 2024-10-01 12:12:56

使用反射来设置受保护的 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);
}

Use reflection to the set the protected DoubleBuffered property:

System.Reflection.PropertyInfo aProp =
         typeof(System.Windows.Forms.Control).GetProperty(
               "DoubleBuffered",
               System.Reflection.BindingFlags.NonPublic |
               System.Reflection.BindingFlags.Instance);

aProp.SetValue(panel1, true, null);

You can also make it more efficient by only invalidating the changed area (this is almost flicker-free even without the double-buffering):

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文