WPF 滚动到 FlowDocument 的末尾

WPF Scroll To End of FlowDocument

我无法让包含在 FlowDocumentScrollViewer 中的 FlowDocument 在其数据更改时滚动到末尾。

这是我的XAML代码

<core:CustomFlowDocumentScrollViewer x:Name="ScrollViewer" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
    <FlowDocumentScrollViewer.Document>
        <FlowDocument PagePadding="0">
            <Paragraph Name="Paragraph"></Paragraph>
        </FlowDocument>
    </FlowDocumentScrollViewer.Document>
</core:CustomFlowDocumentScrollViewer>

core:CustomFlowDocumentScrollViewer 实现了以下代码片段 ,这样我就可以稍后调用 ScrollToBottom()

在我的代码隐藏中,我正在清除 Paragraph 并向其添加新行

private void PopulateFlowDocument(IEnumerable<LoggingEvent> list)
{
    Paragraph.Inlines.Clear();

    foreach (var loggingEvent in list)
    {
        var parsedRun = FormatLoggingEvent(loggingEvent);
        Paragraph.Inlines.Add(parsedRun);
        Paragraph.Inlines.Add(Environment.NewLine);
    }
}

一旦 PopulateFlowDocument 完成,我调用 ScrollToEnd - 控件执行某种程度的滚动,但不能可靠地工作。我的数据源总是 returns 5000 行,但滚动视图只滚动到 ~3750 行(有时更多,有时更少)。

FlowDocument 是否在内部异步工作???

方法二

除了 SO 上可用的解决方案外,我还尝试了 MSDN forum 的以下建议。

void paragraph_Loaded(object sender, RoutedEventArgs e)
{
     Paragraph paragraph = (Paragraph)sender;
     paragraph.Loaded -= paragraph_Loaded;
     paragraph.BringIntoView();
} 

像上面一样,Loaded 事件提前触发,因此滚动不能可靠地工作。

我正在寻找的是 event/notification 整个文档已更新,以便我可以可靠地滚动到其底部。

我最终使用调度程序实现了我想要的。我借用了 here

的想法
Dispatcher.Invoke(new Action(() =>
{
    SearchResultTextBox.ScrollToEnd();
}), DispatcherPriority.ContextIdle, null);           

似乎 FlowDocument 也在使用调度程序,因此滚动需要足够低的优先级,以便在实际文档修改后安排它。