wpf - 检测FlowDocument更改并滚动

标签 wpf scroll flowdocument

我想检测(最好通过事件)何时在FlowDocument中添加,更改等内容,以及何时进行检测,以使显示FlowDocumentScrollViewerFlowDocument自动滚动到末尾。

最佳答案

您可以通过创建文本范围并监视其变化来检测FlowDocument中的变化。滚动到底部更加困难,因为您必须找到ScrollViewer。另外,为了提高性能,您不希望在每次更改时都重做所有滚动计算,因此应使用DispatcherOperations

综上所述,这段代码应该可以解决问题:

var range = new TextRange(flowDocument.ContentStart, flowDocument.ContentEnd);
object operation = null;

range.Changed += (obj, e) =>
{
  if(operation==null)
    operation = Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
    {
      operation = null;

      var scrollViewer = FindFirstVisualDescendantOfType<ScrollViewer>(flowDocument);
      scrollViewer.ScrollToBottom();
    });
};

其中FindFirstVisualDescendantOfType是使用VisualTreeHelper.GetChildrenCount()VisualTreeHelper.GetChild()对视觉树进行的简单的深度优先前缀搜索,并返回找到的第一个指定类型的Visual。

请注意,出于一般性考虑,我不会在代码顶部预先计算scrollViewer,因为FlowDocumentScrollViewer的模板可以更改。如果这不会发生,可以通过在.ApplyTemplate()上调用FlowDocumentScrollViewer,然后在注册事件处理程序之前计算scrollViewer来加快此代码的速度:
var range = new TextRange(flowDocument.ContentStart, flowDocument.ContentEnd);
object operation = null;

flowDocument.ApplyTemplate();
var scrollViewer = FindFirstVisualDescendantOfType<ScrollViewer>(flowDocument);

range.Changed += (obj, e) =>
{
  if(operation==null)
    operation = Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
    {
      operation = null;
      scrollViewer.ScrollToBottom();
    });
};

请注意,由于scrollViewer.GetTemplateChild("PART_ContentHost") protected ,我们不能简单地调用GetTemplateChild并跳过可视树搜索。

关于wpf - 检测FlowDocument更改并滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1655208/

相关文章:

iframe - 在 iframe 中单击子页面时,如何将父页面滚动到顶部?

c# - 跟踪并行 Foreach 线程

android - CoordinatorLayout + TabView + AnimateView(自上而下)

c# - WPF: ListView 在顶部而不是底部显示最近添加的项目

javascript - 单击按钮时水平滚动(视口(viewport)+scrollLeft)

wpf - 定义我要打印的流程文档在页面上的位置为 'start' 和 'end'

c# - 呈现为 XPS 时如何创建带有页眉和页脚的 Xaml FlowDocument?

c# - WPF/C# - 从 XAML 以编程方式创建 FlowDocument?

WPF Combobox - 如何在不滚动的情况下显示两个项目的全部内容?

WPF:如果 UI 元素不可见,则停止绑定(bind)