3

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

これにより、おそらく各ペイント サイクルでパネルが消去されるため、ちらつきが発生します。

4

3 に答える 3

4

OnPaintBackground()をハックするか、WndProc()をハックすることができます。どちらも、独自のクラスを導出する必要があります。それは些細なことです、なぜあなたがそれを避けるのか分かりません。長距離射撃は、WH_CALLWNDPROCフックを備えたSetWindowsHookEx()であり、実際にはばかげています。

于 2010-09-21T18:01:44.347 に答える
0

追加するだけです:

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

シンプルですね。

于 2013-12-13T07:20:49.280 に答える
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);
}
于 2014-10-01T10:22:16.473 に答える