У меня возникли проблемы с получением 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 асинхронно внутри???
Подход 2
Помимо решений, доступных на SO, я также попробовал следующее предложение с форума MSDN .
void paragraph_Loaded(object sender, RoutedEventArgs e)
{
Paragraph paragraph = (Paragraph)sender;
paragraph.Loaded -= paragraph_Loaded;
paragraph.BringIntoView();
}
Как и выше, событие Loaded
срабатывает слишком рано, поэтому прокрутка не работает надежно.
То, что я ищу, - это событие/уведомление, когда весь документ был обновлен, чтобы я мог надежно прокручивать его до самого низа.
В итоге я добился того, что хотел, используя диспетчер. Идею позаимствовал у здесь
Dispatcher.Invoke(new Action(() =>
{
SearchResultTextBox.ScrollToEnd();
}), DispatcherPriority.ContextIdle, null);
Похоже, что FlowDocument также использует диспетчер, поэтому прокрутка должна иметь достаточно низкий приоритет, чтобы она планировалась после фактических изменений документа.