我想在FlowDocument
中检测(最好通过事件)任何内容何时添加,更改等,以及何时会导致FlowDocumentScrollViewer
显示FlowDocument
自动滚动到结尾。检测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()
可视化树,并返回第一视觉找到指定的类型。
请注意,对于完整的通用性,我不会预先计算代码顶部的scrollViewer,因为FlowDocumentScrollViewer
的模板可以更改。如果这不会发生,这个代码可以通过在FlowDocumentScrollViewer
调用.ApplyTemplate()
,然后计算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")
并跳过视觉树搜索因为GetTemplateChild
受保护。
您是否使用RichTextBox进行编辑?如果是这样,你应该可以挂钩the TextChanged
event,然后拨打电话the ScrollToVerticalOffset
method,其值为the ViewportHeight
property。
否使用FlowDocumentScrollViewer,而不是RichTextBox。 – 2009-11-02 12:25:25
挂钩的TextChanged事件后,你可以简单地使用:
// Showing Last Block
YourReader.Document.Blocks.LastBlock.BringIntoView();
// Or.. showing the last Inline
(YourReader.Document.Blocks.LastBlock as Paragraph).Inlines.LastInline.BringIntoView();
但是,这在FlowDocumentPageViewer, 并在FlowDocumentReader工作只(配页ViewingModes),对于FlowDocumentScrollViewer 您应该使用所提及的可视化树
public static ScrollViewer FindScroll(Visual visual)
{
if (visual is ScrollViewer)
return visual as ScrollViewer;
ScrollViewer searchChiled = null;
DependencyObject chiled;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
{
chiled = VisualTreeHelper.GetChild(visual, i);
if (chiled is Visual)
searchChiled = FindScroll(chiled as Visual);
if (searchChiled != null)
return searchChiled;
}
return null;
}
ScrollViewer scroller = FindScroll(YourReader as Visual);
if (scroller != null)
(scroller as ScrollViewer).ScrollToBottom();
我只使用FlowDocument和FlowDocumentscrollViewer。上面的BringIntoView解决方案完全适合我。我不需要VisualTreeHelper 我的解决方案是使用Dispatcher.Invoke编写创建段落,将该段落存储为变量,然后再次将Dispatcher.Invoke放入视图中。 这似乎是最简单的方法。 – 2015-02-25 18:32:38
您可以使用下面的扩展方法来获得内滚动查看器:
public static class FlowDocumentScrollViewerExtensions
{
public static ScrollViewer GetScrollViewer(this FlowDocumentScrollViewer element) {
if (element == null) {
throw new ArgumentNullException(nameof(element));
}
return element.Template?.FindName("PART_ContentHost", element) as ScrollViewer;
}
}
此外,您可以添加内容,检查滚动位置的ScrollViewer本身(要滚动的情况下才使用这些扩展方法 - only-如果滚动观众已经在最后为例):
public static class ScrollViewerExtensions
{
public static bool IsAtHome(this ScrollViewer element) {
if (element == null) {
throw new ArgumentNullException(nameof(element));
}
return element.VerticalOffset <= 0;
}
public static bool IsAtEnd(this ScrollViewer element) {
if (element == null) {
throw new ArgumentNullException(nameof(element));
}
return element.VerticalOffset >= element.ScrollableHeight;
}
}
后来才调用scrollViewer.ScrollToEnd()为例。
- 1. QListView检测滚动更改
- 2. 检测面板中的自动滚动位置值更改
- 3. UIScrollView滚动检测
- 4. 检测UITableView滚动
- 5. jQuery滚动检测
- 6. 的iOS滚动型检测滚动
- 7. Android - 比例和滚动检测器
- 8. 滚轮滚动 - 滚动更改图片
- 9. 检测垂直滚动和滚动条宽度并将宽度更改应用于主体
- 10. 检测更改jQuery
- 11. 更改滚动条
- 12. 更改CSS滚动
- 13. 检测左滚动JavaScript
- 14. 使用scrollTop检测滚动
- 15. 水平检测滚动uitableviewCell
- 16. JQuery检测滚动底部
- 17. jQuery - 检测滚动量
- 18. MonoTouch - 检测UITableView滚动
- 19. Libgdx检测水平滚动
- 20. 检测滚动事件(pdfnet)
- 21. Angular 2自动更改检测周期
- 22. 检测活动何时更改
- 23. 检测动态段中的更改
- 24. 域驱动开发:检测更改(.NET)
- 25. 检测方向和更改类
- 26. 如何检测碎片更改和更改方向
- 27. 检测/监听服务启动和停止状态更改
- 28. 检测是用户已在iOS上滚动,然后更改视图的颜色
- 29. 检测SubmitChanges()前的更改()
- 30. jQuery检测输入更改
我不需要任何与FlowDocument和FlowDocumentScrollViewer可视化树代码。只需2次调用,1就可以创建并添加字符串中的段落,并将该段落添加到视图中。 – 2015-02-25 18:33:43