8

私の WinForm アプリケーションには、多数のアイテムの処理中に進行状況を報告するために使用される複数行の TextBox コントロール (uiResults) があります。AppendText を使用すると、更新のたびに自動的に一番下までスクロールできますが、ユーザーがスクロールして古いデータを読む場合は、自動スクロールをオフにする必要があります。可能であれば、P/Invoke 呼び出しを避けたいと思います。

P/Invoke を使用せずにユーザーがスクロール バックしたかどうかを検出することは可能ですか? 今のところ、動作する SelectionStart を確認するだけですが、自動スクロールを停止するには、ユーザーがキャレットをテキストボックスの最後から移動する必要があります。

if(uiResults.SelectionStart == uiResults.Text.Length)
{
  uiResults.AppendText(result + Environment.NewLine);
}

私の主な問題は、Text プロパティを使用して文字列を追加すると、テキスト ボックスが先頭にスクロールされることです。キャレットの位置を保存し、更新後にリセットしてスクロールすることでこれを解決しようとしましたが、これにより現在の行が一番下に移動します(もちろん、ScrollToCaretはキャレットを表示するために必要な距離を超えてスクロールしないため) )。

[Continued from above]
else
{
  int pos = uiResults.SelectionStart;
  int len = uiResults.SelectionLength;
  uiResults.Text += result + Environment.NewLine;
  uiResults.SelectionStart = pos;
  uiResults.SelectionLength = len;
  uiResults.ScrollToCaret();
}
4

3 に答える 3

4

テキスト ボックスの自動スクロールは、予想よりも多くのメモリを使用します

質問のコードは、探しているものを正確に実装しています。テキストが追加されますが、スクロール バーが一番下にある場合にのみスクロールが発生します。

于 2012-04-16T16:13:07.040 に答える
0

この方法で問題が発生する可能性があり、解決策が複雑になるため (回避したい pinvoke など)、別のアプローチを受け入れますか。たとえば。「ユーザーがスクロールして戻ったかどうかを検出する」方法を見つけて、一番下までスクロールするのをやめたとします。しかし、行を読んだ後、ユーザーは一番下までスクロールする機能を再開したいと思うかもしれません。では、自動スクロールを制御する方法をユーザーに提供してみませんか。これが私がそれを行う方法です...

RichTextBox を使用してデータを表示し、Checkbox を使用して AutoScrolling を制御すると、コードは次のようになります。

        richTextBox1.AppendText(result + Environment.NewLine);
        if (checkBoxAutoScroll.Checked)
        {
            richTextBox1.SelectionStart = richTextBox1.Text.Length;
            richTextBox1.ScrollToCaret(); 
        }

デフォルトでは、RichTextBox は AppendText で自動的に下にスクロールしないため、最初の行は常に表示されます (新しく追加された行ではありません)。しかし、ユーザーが AutoScroll と呼ばれるこのチェックボックスをオンにすると、コードはリッチテキストボックスを新しい行が表示される一番下までスクロールします。ユーザーが手動でスクロールして行を読みたい場合は、最初にチェックボックスをオフにする必要があります。

于 2012-04-17T08:09:30.457 に答える