.Net Compact Framework で Double Buffering

2009/03/19 22:50

.Net Compact Framework では Control.SetStyle メソッドがサポートされていないため、ダブル バッファリングを有効にするここができない。

× SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);

そこで、チラつきを軽減させる方法を調べたところ

  1. 空の Bitmap クラスを作成する
  2. 1.で作成した Bitmap オブジェクトへ描画を行う
  3. この Bitmap オブジェクトを表示する


要は表示したいイメージを作成しておいて、それを一気に表示させるってことかな。

■サンプル

protected override void OnPaint(PaintEventArgs e)
{
    using (Bitmap bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height))
    {
        using (Graphics g = Graphics.FromImage(bmp))
        {
            // 描画処理を行う
        }
        e.Graphics.DrawImage(bmp, 0, 0);
    }
    base.OnPaint(e);
}

#そう言えば昔 VC++ でコントロールを作成してる時にも同じようなことをしていたような気がする。

あ、あれ?チラつくぞ?
少し、描画処理に時間がかかるとやっぱりチラつく。

あれこれ考えた結果、前に表示したイメージを取っておいてそれを先に表示させておいて、それから新しいイメージに置き換えるって方法で、とりあえずチラつきはなくなった。

■サンプル

private Bitmap cachedImg = null;

protected override void OnPaint(PaintEventArgs e)
{
    if (this.cachedImg != null)
    {
        e.Graphics.DrawImage(this.cachedImg, 0, 0); 
        this.cachedImg.Dispose();
    }
    this.cachedImg = new Bitmap(this.ClientSize.Width, this.ClientSize.Height))
    using (Graphics g = Graphics.FromImage(this.cachedImg))
    {
        // 描画処理を行う
    }
    e.Graphics.DrawImage(this.cachedImg, 0, 0);

    base.OnPaint(e);
}

もっとスマートな方法はないのかな?

追記 –2009/06/11-

調べたらちゃんと書いてありました。

protected override void OnPaintBackground(PaintEventArgs e)
{
}

を追加して ベースの OnPaintBackground を呼ばないようにする必要があるようです。

[NCF2.0;C#]

protected override void OnPaintBackground(PaintEventArgs e)
{
}

protected override void OnPaint(PaintEventArgs e)
{
    using (Bitmap bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height))
    {
        using (Graphics g = Graphics.FromImage(bmp))
        {
            // 描画処理を行う
        }
        e.Graphics.DrawImage(bmp, 0, 0);
    }
    base.OnPaint(e);
}

こんな感じで OK でした。

Programing , Permalink

コメント可能な期間を過ぎました