- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
查看this solution为了更好的自动滚动,我认为自己很聪明,找到了一个更简单的解决方案,但它只在调试 session 中有效:
private void scrollviewer_Messages_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
ScrollViewer sv = sender as ScrollViewer;
if (sv.VerticalOffset == sv.ScrollableHeight)
{
sv.ScrollToEnd();//debug breakpoint
}
return;
}
在此 ScrollViewer 中向文本 block 添加内容时,自动滚动有效,文本底部保持在 View 中。当用户向上滚动并添加更多内容时,底部消失,自动滚动关闭,这很好。当用户滚动回到底部时,ScrollToEnd() 应该重新打开自动滚动,但是当添加更多内容时,底部仍然滚动到 View 之外。
当我设置断点时,我可以验证确实调用了 ScrollToEnd()。然后,在删除断点并添加更多内容后,自动滚动再次起作用。
我通过按下按钮、ViewModel 中的代码和绑定(bind)来添加内容。所以我确定没有并发问题。添加内容和手动滚动之间有很多时间。
这真的让我感到困惑,虽然我对我的简单自动滚动解决方案非常满意。这怎么行不通?
编辑:
我发现滚动回到底部后自动滚动又起作用了,但不知何故真正触底并不是那么容易。我需要向下移动 slider ,然后单击滚动条的向下箭头。我现在将尝试替换 ==
登录我的代码以允许几个像素的差异。
编辑:
这个问题会不会是因为内容是一个包含多行文本字符串和TextWrap的TextBlock?
<ScrollViewer Name="scrollviewer_Messages" DockPanel.Dock="Top"
Height="100" Width="200"
ScrollChanged="scrollviewer_Messages_ScrollChanged">
<TextBlock Name="tb_Message"
Margin="10" TextWrapping="Wrap"
Text="{Binding Path=Messages}">
</TextBlock>
</ScrollViewer>
编辑:
将事件处理程序中的公式更改为:
sv.ScrollableHeight - sv.VerticalOffset < 20
我已经尝试过 < 10
但是 pushpraj(见下面的答案)让我尝试了更大的数字。仍然不清楚为什么会这样,因为问题不在于 ScrollToEnd()
没有被调用。
关于解决方案:
<20
不需要,因为它是关于小数的。一般来说,两个实数永远不会相等,但在这里情况并非如此。 double
当 slider 位于末尾时,偏移量和高度的数字实际上是相等的。
问题是,显然,ScrollToEnd/Bottom()
使用 slider 滚动时不起作用。就是这样。我会称之为错误,但它也可能是一个“功能”:当用户滑动 slider 并期望控制时,不应更改 slider 的行为。
解决方法是,首先我们将 slider 滑动到末端,使 Offset == Height。第二步是添加内容会增加高度,由于上面的错误, slider 会向上移动一点点,在我的例子中大约是 15 点。这会引发 ScrollChanged 事件和 <20
的阈值足以接到第二次电话 ScrollToBottom
.每次添加内容时都会执行第二步。
我之前的编辑提到单击向下按钮的工作方式类似。显然,ScrollToEnd 适用于向下按钮。
问题当然是错误就是错误。一次添加更多内容时,阈值可能不起作用,并且自动滚动可能会停止。
最终的解决方案,不像我希望的那么简单,但也不会太复杂,应该是我下面的答案。
最佳答案
问题的原因是 ScrollToEnd()
与自动滚动无关。这个调用只是滚动到最后,就是这样。通过将调用放在事件处理程序中,它会经常滚动到末尾,但对于真正的自动滚动,有必要确定是谁触发了事件:用户通过移动 slider ,或者由于内容大小的变化而移动 slider 。不再通过查看 ExtentHeight
来忽略“无用”事件,而是使用此属性来确定触发事件的人或事件。
此解决方案将自动滚动位的状态保存在控件的标记中。将新的用户控件 AutoScrollViewer 子类化会更好。
毕竟,这个解决方案并不比问题中上面提到的以前的解决方案“简单”多少,它只是一个变体,但(希望)更准确。
/// <summary>
/// If the scrollviewer is at the bottom, keep the bottom in view.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void scrollviewer_Messages_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
ScrollViewer sv = sender as ScrollViewer;
bool AutoScrollToEnd = true;
if (sv.Tag != null)
{
AutoScrollToEnd = (bool)sv.Tag;
}
if (e.ExtentHeightChange == 0)// user scroll
{
AutoScrollToEnd = sv.ScrollableHeight == sv.VerticalOffset;
}
else// content change
{
if (AutoScrollToEnd)
{
sv.ScrollToEnd();
}
}
sv.Tag = AutoScrollToEnd;
return;
}
关于c# - 使用 ScrollViewer.ScrollToEnd() 执行 AutoScroll 仅在调试时有效,事件处理程序太简单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25761795/
当数据完全加载时,如何滚动到平面列表的底部。 我认为通过调用应该可以 componentDidMount 函数中的 this._flatList.scrollToEnd() 。这对我有用。 如果我使用
我正在尝试调用一个将在 TextInput 上触发 onFoucs 的函数这将滚动 ScrollView 一直向下(使用 scrollToEnd() ) 所以这是我的类组件 class MyCMP e
我的 WPF 应用程序中的 RichTextBox 组件是使用 FlowDocument 和 RichTextBox 的 Document 属性填充的. rtb.ScrollToEnd(); 似乎没有
嗨,我尝试解决这个问题,在 WPF 中我使用 Caliburn Micro 框架。在 View 中,我有可绑定(bind)的 Richtextbox 控件,我从 FlowDocument 的 View
我正在使用 Flatlist 制作一个聊天框。我想向数据添加一个新项目,然后滚动到列表底部。我使用 scrollToEnd 方法,但它不起作用。我怎样才能做到这一点? {item.chat}} />
我正在对加速度计传感器进行采样并实时显示图表,使用 Graph View库 (4.0.1)。 该应用程序运行良好,但图表有误: 正如您在图片中看到的,Z 轴(洋红色)的值为 ~9.8 但在图中显示为
我使用了 ListView 的 scrollToEnd,但它不起作用,但它适用于 scrollTo。我应该如何处理它。 最佳答案 有一个解决方法,将其包装在 setTimeout 中,如下所示: co
我们的应用程序启动几个后台进程并将它们的输出放入 TextBoxes - 每个在 TabControl 中的一个单独的 TabItem。我希望 TextBoxes 自动滚动以显示最后一个输出行,因此在
我正在使用新的 FlatList component并想利用 ScrollToIndex (或 ScrollToEnd )在生命周期方法中,例如 componentDidMount . 我有一个比方说
查看this solution为了更好的自动滚动,我认为自己很聪明,找到了一个更简单的解决方案,但它只在调试 session 中有效: private void scrollviewer_Me
我是一名优秀的程序员,十分优秀!