0

我在将 FlowDocument 包装在 FlowDocumentScrollViewer 中以在其数据更改时滚动到末尾时遇到问题。

这是我的 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实现了以下代码片段https://stackoverflow.com/a/561319/13567181 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- 控件执行某种程度的滚动,但不能可靠地工作。我的数据源总是返回 5000 行,但滚动视图只滚动到 ~3750 行(有时更多,有时更少)。

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

方法二

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

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

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

我正在寻找的是整个文档已更新时的事件/通知,以便我可以可靠地滚动到它的最底部。

4

1 回答 1

0

我最终使用调度程序实现了我想要的。我从这里借用了这个想法

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

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

于 2020-12-10T18:07:45.357 回答