4

RichTextBox特定のイベントで新しいコンテンツを取得しているアプリを持っています。新しいコンテンツが追加されたら、以前にスクロールが一番下にあった場合にのみ
、一番下までスクロールしたいと思います。 どうすればいいですか? より具体的には、私が苦労するのはスクロール位置の決定です。

問題があればRichTextBox、デフォルトのスタイルとテンプレートを使用し、いくつかのブラシを変更または null に設定し、垂直スクロールバーの可視性を Auto にし、読み取り専用にします。

4

4 に答える 4

3

スクロールバーが一番下にドラッグされたときにのみ、リッチテキストボックスが新しく追加されたテキストで自動スクロールするようにしたい場合は、プロジェクトに次のクラスを追加します

public class RichTextBoxThing : DependencyObject
{
    public static bool GetIsAutoScroll(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsAutoScrollProperty);
    }

    public static void SetIsAutoScroll(DependencyObject obj, bool value)
    {
        obj.SetValue(IsAutoScrollProperty, value);
    }

    public static readonly DependencyProperty IsAutoScrollProperty =
        DependencyProperty.RegisterAttached("IsAutoScroll", typeof(bool), typeof(RichTextBoxThing), new PropertyMetadata(false, new PropertyChangedCallback((s, e) =>
            {
                RichTextBox richTextBox = s as RichTextBox;
                if (richTextBox != null)
                {
                    if ((bool)e.NewValue)
                        richTextBox.TextChanged += richTextBox_TextChanged;
                    else if ((bool)e.OldValue)
                        richTextBox.TextChanged -= richTextBox_TextChanged;

                }
            })));

    static void richTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        RichTextBox richTextBox = sender as RichTextBox;
        if ((richTextBox.VerticalOffset + richTextBox.ViewportHeight) == richTextBox.ExtentHeight || richTextBox.ExtentHeight < richTextBox.ViewportHeight)
            richTextBox.ScrollToEnd();
    }
}

次に、自動スクロール動作が必要なリッチテキストボックスにIsAutoSrollプロパティを追加します

<RichTextBox ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" local:RichTextBoxThing.IsAutoScroll="True"/> 
于 2012-11-19T15:25:42.830 に答える
3

スクロールするためのはるかに単純な条件はVerticalOffset + ViewportHeight >= ExtentHeight

例:

bool shouldScroll = rtbx.VerticalOffset + rtbx.ViewportHeight >= 
                    rtbx.ExtentHeight;

// changes to RichTextBox 
// ...

if(shouldScroll) rtbx.ScrollToEnd();

「スクロールバーが表示されたばかり」の場合にも機能します。

于 2013-09-12T13:16:17.373 に答える
1

基本的に次のことができます: スクロールバーを取得し、 、および の変更をサブスクライブしますValue(MaximumこれらMinimumはすべて依存関係プロパティです)。Valueこのようにして、必要なときにMaximumいつでも を設定することで、コード ビハインドの位置を制御できます。

では、どうすればスクロールバーにアクセスできますか? いくつかの方法があります。のコントロール テンプレートがどれかわかっている場合は、RichTextBoxを使用して取得できますGetTemplateChild(name)(たとえば、Blend でテンプレートを調べて名前を取得します)。よくわからない場合は、独自のテンプレートを作成して (ここでも、Blend が最初に適切なテンプレートを提供します)、それをRichTextBox興味のある に適用することをお勧めします。

于 2012-11-19T15:18:57.887 に答える
0

この拡張メソッドを試してください:

public static class RichTextBoxExtensions
{
    public static void ScrollIfNeeded(this RichTextBox textBox)
    {
        var offset = textBox.VerticalOffset + textBox.ViewportHeight;
        if (Math.Abs(offset - textBox.ExtentHeight) > double.Epsilon) return;
        textBox.ScrollToEnd();
    }
}

そして、次のように使用します。

textBox.AppendText(// Very long text here);
textBox.ScrollIfNeeded();

編集:スクロールバーが表示されたときに下にスクロールするなどの代替手段:

public static class RichTextBoxExtensions
{
    public static void ScrollIfNeeded(this RichTextBox textBox)
    {
        var offset = textBox.VerticalOffset + textBox.ViewportHeight;
        if (Math.Abs(offset - textBox.ExtentHeight) <= double.Epsilon)
        {
            textBox.ScrollToEnd();
        }
        else
        {
            var contentIsLargerThatViewport = textBox.ExtentHeight > textBox.ViewportHeight;
            if (Math.Abs(textBox.VerticalOffset - 0) < double.Epsilon && contentIsLargerThatViewport)
            {
                textBox.ScrollToEnd();
            }
        }
    }
}
于 2012-11-19T15:30:55.567 に答える