Отключить OnPaintBackground без создания подкласса Panel? - PullRequest
3 голосов
/ 21 сентября 2010

Есть ли способ отключить стирание панели без создания подкласса 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);
    }
}

Это вызывает мерцание, предположительно, потому что стирает панель при каждом цикле рисования.

Ответы [ 3 ]

4 голосов
/ 21 сентября 2010

Вы можете взломать OnPaintBackground () или вы можете взломать WndProc (). Либо требует создания своего собственного класса. Это тривиально, я просто не понимаю, почему бы тебе этого избежать. Дальний выстрел - это SetWindowsHookEx () с крюком WH_CALLWNDPROC, слишком глупо.

0 голосов
/ 01 октября 2014

Используйте отражение, чтобы установить защищенное свойство 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);
}
0 голосов
/ 13 декабря 2013

Просто добавьте:

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

Просто не так ли?

...