当我添加新行时,如何使富文本框滚动到末尾

本文关键字:滚动 文本 何使富 添加 新行时 | 更新日期: 2023-09-27 18:32:20

我有几个只读的RichTextBox用于记录输出。由于它们是只读的,因此在更新文本时它们似乎不会自动滚动。 我可以使用 TextChanged 事件强制滚动结束,但是有没有一种方法可以在 XAML 中设置属性或内容,以便滚动正常发生?

当我添加新行时,如何使富文本框滚动到末尾

我已经用谷歌搜索了你的问题并找到了这篇文章。在"Programming the RichTextBox"一节中,作者描述了如何获得您所期望的行为。

请检查并让我知道它是否有任何用处。


我试图重现您的问题并提出了以下解决方案

    <Window x:Class="CheckRichTextBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="170" Width="300">
    <StackPanel>
        <RichTextBox Height="100" Name="richTextBox1" IsReadOnly="True" VerticalScrollBarVisibility="Visible"/>
        <Button Name="btnAdd" Content="Click me to add text" VerticalAlignment="Bottom" Click="BtnAddClick" />
    </StackPanel>
</Window>

相同的代码隐藏如下:

using System.Windows;
namespace CheckRichTextBox
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void BtnAddClick(object sender, RoutedEventArgs e)
        {
            richTextBox1.AppendText("You had Clicked the button for adding text'n");
            richTextBox1.ScrollToEnd();
        }
    }
}

这解决了自动滚动的问题,请检查它并让我知道它是否有任何帮助。

我使用交互触发器和一个非常简单的操作解决了这个问题。

操作如下所示:

public class ScrollToBottomAction : TriggerAction<RichTextBox>
{
    protected override void Invoke(object parameter)
    {
        AssociatedObject.ScrollToEnd();
    }
}

然后在我的 XAML 中,我有这个:

<RichTextBox IsReadOnly="True" VerticalScrollBarVisibility="Auto">
     <i:Interaction.Triggers>
            <i:EventTrigger EventName="TextChanged">
                <interactivity:ScrollToBottomAction/>
            </i:EventTrigger>
     </i:Interaction.Triggers>
</RichTextBox>

我想出了以下 wpf 富文本框自动滚动的解决方案

public partial class MainWindow
{
    private bool AutoScroll = true;
    public MainWindow()
    {
        InitializeComponent();
        yourRichTextBox.Loaded += (s, e) =>
          {
              var scrollViewer = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(yourRichTextBox, 0), 0) as ScrollViewer;
              scrollViewer.ScrollChanged += (scroller, eScroller) => ScrollViewer_ScrollChanged(scroller, eScroller);
          };
    }
    private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        // User scroll event : set or unset autoscroll mode
        if (e.Source as ScrollViewer != null && e.ExtentHeightChange == 0)
        {   // Content unchanged : user scroll event
            if ((e.Source as ScrollViewer).VerticalOffset == (e.Source as ScrollViewer).ScrollableHeight)
            {   // Scroll bar is in bottom
                // Set autoscroll mode
                AutoScroll = true;
            }
            else
            {   // Scroll bar isn't in bottom
                // Unset autoscroll mode
                AutoScroll = false;
            }
        }
        // Content scroll event : autoscroll eventually
        if (AutoScroll && e.ExtentHeightChange != 0 && e.Source as ScrollViewer != null)
        {   // Content changed and autoscroll mode set
            // Autoscroll
            (e.Source as ScrollViewer).ScrollToVerticalOffset((e.Source as ScrollViewer).ExtentHeight);
        }
    }
}

这是在 C# 中执行此操作的方法

将 RichTextBox 放在 ScrollViewer 中,如下所示:

scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;

scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;

scrollViewer.Content = rTextBox;

然后将 scrollViewer 添加到网格或您正在使用的任何内容。

RootGrid.Children.Add(scrollViewer);

(这是在 C# 中,但也可以在 XAML 中完成。

然后使用如下所示的 C# 代码使其在添加文本时滚动到底部:

rTextBox.AppendText(str);
scrollViewer.ScrollToEnd();

希望有帮助。

RichTextBox.AppendText("String")
RichTextBox.ScrollToCaret()

当我添加到 RichTextBox.text 时,ScrollToCaret() 不起作用。

RichTextBox.text = RichTextBox.text + "String"
RichTextBox.ScrollToCaret()