19

Windows フォームのちらつきに対処する記事はたくさんあります。大多数は、一連のフラグを設定DoubleBuffered = trueまたは設定することをお勧めします。ControlStyleただし、これらのどれも TextBox のちらつきを減らすのに役立ちません。

関連するいくつかの質問を次に示します。

この問題を再現するには、新しい WinForms プロジェクトを作成しTextBoxAnchor. 実行してサイズを変更します。文字がちらつく。いくつかのネストされた 内のテキスト ボックスの場合TableLayoutPanel、サイズ変更時のちらつきはさらに悪化します。

上記の質問で提案された解決策を適用しても、ちらつきは修正されません。実験的になり、保護ControlStyleをオンTextBoxに設定すると、(を有効にすることで)完全に壊すことができますUserPaintが、ちらつきをなくすことはできません。

では、TextBox 内のテキストのちらつきを修正する方法はありますか?

4

4 に答える 4

16

私は通常、複数行の TextBox の代わりにRichTextBoxを使用します。DetectUrls- および ShortcutsEnabled- プロパティを false に設定すると、RTB は TextBox と非常によく似た動作をし、ちらつきがなくなります

于 2011-04-15T14:45:17.080 に答える
4

Windows フォームでは、DoubleBuffered プロパティはテキスト ボックスなどの子コントロールには影響しません。代わりに、設定されているフォームまたはパネルだけに影響します。

フォームの子要素のダブル バッファリングが必要な場合は、手動のダブル バッファリングを実装する必要があります。

Bob Powell は、これを行う方法について優れた記事(および他の記事) を書いています。

また、フォーラムの回答から、ボブも次のように述べています。

ウィンドウの所有権は、ターゲット ウィンドウ領域の外側でダブル バッファリングできないため、ウィンドウが制御不能にちらつくことを意味します。子コントロールを持つパネルは、それ自体をダブル バッファにすることはできません 。たとえば、それは子です

これを正しく行う唯一の方法は、保持モード グラフィックス システムの形式を使用してすべての描画を行う単一のコントロールを作成することです。

したがって、手動のダブルバッファリングを使用してちらつきのないテキストボックスのサイズを変更するには、何らかの方法でテキストボックスをバック バッファにレンダリングしてから、バッファリングされた更新の一部として表示する必要があります。可能であれば:これが簡単になるとは思いません。

[アップデート]

他のいくつかの回答では、これは特に Windows フォームの問題であると述べています。これは正しくありません。実際にはそれよりも深く、Windows GDI が原因です。例として、メモ帳/ワードパッドなどを開いて大量のテキストを貼り付け、ウィンドウのサイズを変更すると、同じちらつきの問題が発生します。

これは、私が何年も前に同様のことを行うために使用した基本的なソリューションです。これは、複数行のテキスト ボックスと、Panel から継承したカスタム クラスを含む単純なフォームです。両方のコントロールの位置とサイズは同じです。フォームの ResizeBegin と ResizeEnd を使用して、サイズ変更時にパネルを表示し、それ以外の場合はテキスト ボックスを表示します。完全ではありませんが、ちらつきはなくなります。

   public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Bitmap bm = null;

        private void textBox1_Resize(object sender, EventArgs e)
        {

            Graphics g = textBox1.CreateGraphics();

            if (g.VisibleClipBounds.IsEmpty == false)
            {
                bm = new Bitmap((int)g.VisibleClipBounds.Width, (int)g.VisibleClipBounds.Height);

                textBox1.DrawToBitmap(bm, new Rectangle(0, 0, (int)g.VisibleClipBounds.Width, (int)g.VisibleClipBounds.Height));

            }

            g.Dispose();


        }

        private void panelDB1_Paint(object sender, PaintEventArgs e)
        {
            if (bm != null)
            {
                e.Graphics.DrawImageUnscaled(bm, 0, 0,bm.Width,bm.Height );
            }
        }

        private void Form1_ResizeBegin(object sender, EventArgs e)
        {
            panelDB1.BringToFront();  
        }

        private void Form1_ResizeEnd(object sender, EventArgs e)
        {
            panelDB1.SendToBack();   
        }
}

class PanelDB : Panel
{
    public PanelDB()
    {
        this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer,true);       
        //this.DoubleBuffered = true; 
    
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
    }
}
于 2009-08-26T09:59:14.920 に答える
0

過去に同様の問題に遭遇したことがありますが、それはドッキングとテーブル レイアウト パネルの過剰な使用であることが判明しました。可能であれば、ドッキングの使用を最小限に抑えて UI を再構築することをお勧めします (テーブル レイアウト パネルも内部でドッキングを使用するため)。

于 2009-08-26T09:52:18.663 に答える
-3

FUNCTION LockWindow AS LONG CONTROL SEND ghDlg, %TEXT_UPPER,%WM_SETREDRAW,0,0 CLEARBuffers END FUNCTION

FUNCTION UnlockWindow AS LONG ClearBuffers CONTROL SEND ghDlg,%TEXT_UPPER,%WM_SETREDRAW,1,0 END FUNCTION

于 2015-12-01T04:53:04.327 に答える