2

ちらつきが非常に悪いWinformユーザーコントロールがあります。コントロールの機能は完璧に機能しています。ちらつきが本当にひどいです。ビットマップにすべての描画を行ってから、DrawImageビットマップを画面にコピーするだけなので、ちらつきの量に驚いています。ここに私が持っているものの抜粋があります:

    private void ScrollPanel_Paint(object sender, PaintEventArgs e)
    {
        var c = (Calendar)Parent;

        Bitmap bmp = c.RequestImage();
        if (bmp == null)
            return;

        e.Graphics.DrawImage(bmp, new Rectangle(0, 0, ClientSize.Width, ClientSize.Height),
                             new Rectangle(0, _scrollOffset, ClientSize.Width, ClientSize.Height),
                             GraphicsUnit.Pixel);
        _bmpSize = bmp.Height;
        e.Graphics.Dispose();
        bmp.Dispose();
    }

    private void ScrollPanel_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            _mouseDown = true;
            _oldMouseCoords = e.Location;
        }
    }

    private void ScrollPanel_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
            _mouseDown = false;
    }

    private void ScrollPanel_MouseMove(object sender, MouseEventArgs e)
    {
        if (_mouseDown && e.Location.Y < _oldMouseCoords.Y && _scrollOffset < _bmpSize - _scrollOffset - ClientSize.Height)
        {
            int offset = _oldMouseCoords.Y - e.Location.Y;
            _scrollOffset += offset;
            Refresh();
        }
        if (_mouseDown && e.Location.Y > _oldMouseCoords.Y && _scrollOffset > 0)
        {
            int offset = e.Location.Y - _oldMouseCoords.Y;
            _scrollOffset -= offset;
            Refresh();
        }
        _oldMouseCoords = e.Location;
    }

マウスでドラッグすると、ビットマップがスクロールされるはずです。私が言ったように、機能はすべて機能しています。イベントからわかるようPaintに、ビットマップを取得して画面に直接コピーするだけです。

どんな助けでも大歓迎です。

4

1 に答える 1

3

ダブルバッファリングに関するこの他の質問を見て、正しく設定していることを確認してください... ダブルバッファリングを有効にする

私の経験では、ダブル バッファリングが設定されると、すべてのペイントを自分で行うことを選択した場合でも、コントロールの背景がペイントされることによってちらつきが発生します。これを回避するには、描画されるコントロール クラスから独自のコントロール クラスを派生させ、OnPaintBackground メソッドをオーバーライドし、そのメソッドで基本クラスの実装を呼び出さないようにしました。

したがって、あなたの場合、 ScrollPanel は Panel であると想定しています。Panel からクラスを派生させ、Panel の代わりにそれを使用します。次に、OnPaintBackground をオーバーライドし、そのメソッドの本体を空のままにします。

以上のことをすべて行った後、WinForms が達成できるのとほぼ同じくらいスムーズなスクロールができました。

于 2012-05-03T10:55:40.207 に答える