14

WinFormsアプリケーションには、ログファイルとして使用しているTextBoxがあります。を使用してフォームのちらつきなしでテキストを追加していますが、TextBox.AppendText(string);古いテキストを削除しようとすると(コントロールの.Textプロパティが.MaxLength制限に達すると)、ひどいちらつきが発生します。

私が使用しているコードは次のとおりです。

public static void AddTextToConsoleThreadSafe(TextBox textBox, string text)
{
    if (textBox.InvokeRequired)
    {
        textBox.Invoke(new AddTextToConsoleThreadSafeDelegate(AddTextToConsoleThreadSafe), new object[] { textBox, text });
    }
    else
    {
        // Ensure that text is purged from the top of the textbox
        // if the amount of text in the box is approaching the
        // MaxLength property of the control

        if (textBox.Text.Length + text.Length > textBox.MaxLength)
        {
            int cr = textBox.Text.IndexOf("\r\n");
            if (cr > 0)
            {
                textBox.Select(0, cr + 1);
                textBox.SelectedText = string.Empty;
            }
            else
            {
                textBox.Select(0, text.Length);
            }
        }


        // Append the new text, move the caret to the end of the
        // text, and ensure the textbox is scrolled to the bottom

        textBox.AppendText(text);
        textBox.SelectionStart = textBox.Text.Length;
        textBox.ScrollToCaret();
    }
}

ちらつきを引き起こさない、コントロールの上部からテキストの行を削除するすてきな方法はありますか?テキストボックスには、ListViewにあるBeginUpdate()/ EndUpdate()メソッドがありません。

TextBoxコントロールは、コンソールログに最適なコントロールでさえありますか?

編集:TextBoxのちらつきは、テキストボックスが上にスクロールしているように見え(コントロールの上部にあるテキストを削除している間)、すぐに下にスクロールして戻ります。-すべてが非常に迅速に行われるため、ちらつきが繰り返されます。

私もこの質問を見たばかりで、リストボックスを使用することを提案しましたが、(ほとんどの場合)リストボックスのテキストを1文字で受信しているため、これが私の状況で機能するかどうかはわかりません。時間。

4

6 に答える 6

18

Mathijsの答えは私のために働きます。任意のコントロールで使用できるように少し変更しました-コントロール拡張:

namespace System.Windows.Forms
{
    public static class ControlExtensions
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern bool LockWindowUpdate(IntPtr hWndLock);

        public static void Suspend(this Control control)
        {
            LockWindowUpdate(control.Handle);
        }

        public static void Resume(this Control control)
        {
            LockWindowUpdate(IntPtr.Zero);
        }

    }
}

だからあなたがする必要があるのは:

myTextBox.Suspend();
// do something here.
myTextBox.Resume();

うまく機能します。すべてのちらつきが止まります。

于 2013-07-28T22:23:32.987 に答える
13

私はインターネットで解決策を見つけました:

    [System.Runtime.InteropServices.DllImport("user32.dll")]

    public static extern bool LockWindowUpdate(IntPtr hWndLock);

    internal void FillTB(TextBox tb, string mes) 
    {
       try
       {
          LockWindowUpdate(tb.Handle);

          // Do your thingies with TextBox tb
       }
       finally
       {
          LockWindowUpdate(IntPtr.Zero);
       }
    }
于 2012-02-02T14:55:25.153 に答える
4

メインウィンドウにダブルバッファリングを設定しましたか?

InitializeComponent呼び出し後のコンストラクターのこのコードは、二重バッファーを追加し、ちらつきを減らす可能性があります。

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

于 2009-10-11T10:03:13.083 に答える
3

SelectedText = textを使用すると、ちらつきが大幅に減少することがわかりました。非常に高速な更新の場合、ちらつきは新しいテキストのみにローカライズされ、スクロールバーがジャンプして奇妙な動作をすることはありません。

void UpdateTextBox(string message)
{
   myTextBox.SelectionStart = myTextBox.Text.Length;
   myTextBox.SelectedText = message;
}

これを使用して、以前に書き込まれたテキストを上書きすることもできます。たとえば、カウンターを更新したり、パーセンテージをダウンロードしたりする必要があるためです。

void UpdateTextBox(string message, int jumpBack)
{
   myTextBox.SelectionStart = Math.Max(myTextBox.Text.Length - jumpBack, 0);
   myTextBox.SelectionLength = jumpBack;
   myTextBox.SelectedText = message;
}

それ以外に、.NETTextBoxのちらつきを減らす簡単な方法はないようです。

于 2011-11-02T17:52:20.473 に答える
2

すべての更新操作でSuspendLayout()/ ResumeLayout()を試しましたか?

テキストボックスでClear()を呼び出してから、切り捨てられたテキストを再割り当てすることもできます。

ある種のログファイルビューアを実装しようとしている場合は、代わりにListBoxを使用できます。

于 2009-10-11T10:07:23.427 に答える
2

問題は、一度に1つの文字を繰り返してすばやく追加(削除)していることです。1つの解決策は、追加される文字をバッファリングし、テキストボックスをより大きな間隔で(文字数に関係なく)、たとえば250ミリ秒ごとに更新することです。

これには以下が必要です。

  • 追加される文字の配列またはスタックを作成する
  • スタックに格納されている文字で実際に更新を行うデリゲートを呼び出すタイマーを設定する

もう1つのオプションは、最初に何が起こっても、250ミリ秒ごとと100文字ごとの両方を使用することです。しかし、これはおそらく、具体的なメリットがなければ、コードをさらに複雑にするでしょう。

于 2009-10-11T10:29:53.073 に答える