RichTextBox当不可见时无法滚动到末尾

4
我的应用程序中有一个WPF RichTextBox控件,它位于Grid中。它每隔一秒或两秒更新一次,显示日志(不过有时根据负载情况可能长达一分钟没有日志可显示)。
由于该Grid处于自己的选项卡中,因此该Grid并非总是可见的。如果用户在另一个标签上,则记录器将不可见。
我的问题是,每添加一个新段落,我希望RichTextBox始终滚动到末尾。看起来很简单,因为RichTextBox控件上有一个“ScrollToEnd”方法,所以每次向控件添加文本时,我都会调用该方法。
问题是,如果控件不可见,该方法仅在控件可见时才起作用。如果用户在另一个标签上,RichTextBox将无法滚动到底部,当您点击带有记录器的选项卡且经过几秒钟或更长时间后,它才会滚动到底部,这看起来很奇怪。
有没有办法解决控件的这个恼人的“功能”?我希望始终将RichTextBox置于底部,除非用户手动控制滚动条。
谢谢!
2个回答

3

默认情况下,TabControl实际上不会改变其内容的可见性,当您切换选项卡时,它会完全从视图中删除它们,然后在您导航回先前的选项卡时“重新连接”它们。

这就是为什么可见性更改不会被触发的原因。相反,您应该处理Loaded事件,该事件应该在重新呈现视图之前触发。


这完美地解决了我的问题,现在我已经钩住了加载事件,一切都很完美!我简直不敢相信我从来没有想过这个,我一直以为它只是改变可见性而不是被移除和再次添加。赏金已颁发。 - Landin Martens
这个问题相当反直觉,而且文档也没有很好的记录:P 我们也是通过大量的试错和最终使用Snoop来检查可视树才发现的 - 发现每次只有一个TabItem的内容被渲染!(感谢悬赏:)) - almulo

1

你是否有不能简单调用ScrollToEnd来响应文本框可见的原因?那似乎是最简单的方法。你尝试过并遇到问题了吗?

编辑:如果你正在使用TabControl,每个TabItem都有一个IsSelected属性,你可以从ItemContainerStyle中绑定到它。你可能可以在选项卡被选中时滚动你的文本框。


作为一个额外的注意事项:如果您计划为此创建自定义控件,这里有一些需要考虑的事情。
我编写了一个自动滚动版本的FlowDocumentScrollViewer。(我从未特别需要RichTextBox,但它们显示类似的内容。)我可以告诉您,有很多要考虑的事情,比如根据用户当前的操作来确定何时自动滚动和何时不滚动。
例如:
- 如果用户通过滚动条或鼠标滚轮自己滚动,则不希望控件与他们抗争。 - 如果他们开始选择文本,则不希望在选择期间将其滚动走。 - 如果他们滚动到底部,则可能希望它重新开始自动滚动。
此外,确定用户正在做什么有时可能是一个复杂的过程。

我尝试钩入可见变化事件,但当用户切换到不同的选项卡并返回时,它没有触发。我尝试了所有事件,但找不到一个总是在事件再次可见/渲染时触发的。我不想制作自定义控件,这更像是“如果我必须”的事情。我更喜欢找到另一种解决方案,允许我使用当前控件。 - Landin Martens
如果您正在使用 TabControl,每个 TabItem 都有一个 IsSelected 属性可以从 ItemContainerStyle 绑定。您可能可以在选项卡被选中时滚动文本框。 - Xavier
我们使用类似的东西,不是常规的TabItem / TabControl,但足够接近。这确实给了我一个好主意去尝试,以前出于某种原因我从未想过。如果它有效,我会接受你的答案。即使它不是我的确切解决方案,答案本身我认为仍然是其他人可以在未来使用/看到的好答案。 - Landin Martens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接