我想检测(最好通过事件)何时在FlowDocument
中添加,更改等内容,以及何时进行检测,以使显示FlowDocumentScrollViewer
的FlowDocument
自动滚动到末尾。
最佳答案
您可以通过创建文本范围并监视其变化来检测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/