【发布时间】:2020-08-05 16:00:45
【问题描述】:
今天我正在寻找一种滚动多行、动态大小的文本框的方法。
我想滚动到插入符号,但在互联网上找不到任何有用的信息。
在尝试了很多事情之后,我知道如何滚动到行尾,但不知道如何滚动到插入符号。 向右滚动已经实现了,但是水平滚动部分已经没有了。
private void txtText_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Down || e.Key == Key.Up)
{
var CurrentLineIndex = txtText.GetLineIndexFromCharacterIndex(((TextBox)sender).SelectionStart);
txtText.ScrollToLine(CurrentLineIndex);
}
}
这是我当前的代码,它会为我滚动到正确的行。
尝试为水平滚动做一些类似的事情:
var rect = ((TextBox)sender).GetRectFromCharacterIndex(((TextBox)sender).CaretIndex);
txtText.ScrollToHorizontalOffset(Math.Max((txtText.HorizontalOffset + rect.Right - (txtText.ActualWidth - 40)), 0.0));
但它不像预期的那样工作,它不会滚动到水平插入符号位置。
想想,我必须更好地描述它:
如果我用左箭头或右箭头移动插入符号,它会在不执行任何操作的情况下正常工作。
如果我这样做,它不起作用:
从一行移到另一行。 有时其中一行比另一行长或短,在这种情况下,我必须滚动到插入符号的位置。
示例:
Line1 比 line2 长
我用键盘上的“end”键导航到 line1 的末尾。
然后我导航到第 2 行。
一切正常,插入符号跳到第2行的末尾,它会自动滚动到可见区域。
但如果我从第 2 行返回第 1 行,插入符号位于第 1 行的末尾。但它不会滚动到第 1 行的末尾。
【问题讨论】:
-
我很确定你想要的已经是默认行为了。默认情况下,
TextBox会在之前按下 End 键时滚动到行尾。同样默认情况下,TextBox会将插入符号移动到按键向下/向上的下一行/上一行。默认情况下,插入符号位置滚动到视图中。您的手动行滚动正在破坏这种行为。我也怀疑你的代码实际上是在做你认为它做的事情。在您的代码执行之前,TextBox已经处理了关键事件。 -
如果您将事件标记为已处理,您可能会意识到您的代码实际上什么也没做。显然
TextBox最终是围绕关键事件构建的——它是一个文本输入控件。有很多按键处理正在进行,大多数事件处理实际上是延迟的,导致客户端处理程序操作被覆盖。我想知道您为什么认为需要为TextBox重新实现键盘处理。 -
是的,我也认为这是为文本框处理的标准。但似乎,这并不容易。似乎所有这些好行为只有在文本框具有固定大小时才起作用。阅读一些文章,滚动查看器不能处理元素的动态大小。据我所知,文本框中使用了一个(不是来自我,而是根据定义),我认为这应该是问题所在。如果没有我对向下和向上箭头的处理,文本框将不会滚动到正确的行。
-
我发现了问题。没想到,一个样式模板会影响到如此奇怪的行为——即使它是基于这些元素并且默认样式没有被覆盖。因为我有一个圆形文本框,所以我也必须修改滚动条。想要使用滚动查看器的样式模板来做到这一点。这些以这种奇怪的行为结束。现在我只为滚动条使用模板,它可以正常工作......因此解决了 - 我认为以另一种方式解决,但它工作......将其标记为已解决,但找不到如何解决。
标签: wpf scroll textbox multiline caret