我之前的post here显示了如何获取RichTextbox中水平或垂直滚动条的位置。但是,这些仅在启用滚动条时有效。如果您将滚动条设置为无(通过richTextBox1.ScrollBars = RichTextBoxScrollBars.None;
),那么您仍然可以向下滚动框的底部(如果禁用WordWrap则向右滚动)。但是,getVerticalScroll()
和getHorizontalScroll()
方法(如我发布的链接中所示)现在只返回0。他们似乎需要“看到”滚动条才能真正发挥作用。
那么如何在滚动条被禁用的情况下获取(并设置)'滚动位置'?
答案 0 :(得分:6)
RichTextBox类有几个辅助方法,可以让您发现窗口内文本的位置。这是您需要在这里使用的内容,因为您不再需要滚动条的直接反馈。
您可以找到哪条线显示为RichTextBox.GetCharIndexFromPosition()的第一条可见线,以查找第一个可见字符,然后是GetLineFromCharIndex()以找出包含该字符的行:
public static double GetVerticalScrollPos(RichTextBox box) {
int index = box.GetCharIndexFromPosition(new Point(1, 1));
int topline = box.GetLineFromCharIndex(index);
int lines = box.Lines.Length;
return lines == 0 ? 0 : 100.0 * topline / lines;
}
通过查看插入符当前所在的行,可以找到水平滚动位置。并将行的开头映射回位置:
public static double GetHorizontalScrollPos(RichTextBox box) {
int index = box.SelectionStart;
int line = box.GetLineFromCharIndex(index);
int start = box.GetFirstCharIndexFromLine(line);
Point pos = box.GetPositionFromCharIndex(start);
return 100 * (1 - pos.X) / box.ClientSize.Width;
}
您可能想重新定义100%的含义,原始问题没有提供任何指导。
这个问题具有XY Problem的各个方面,它会让你真正想要做的就是用更大的滚动条替换滚动条。不要忽略这个愚蠢的简单解决方案,您可以通过正确放置现有的解决方案覆盖现有的解决方案,以便它们重叠并隐藏它们。你只需要改变边框,这样就不那么明显了。
答案 1 :(得分:5)
我想你会找到一些有趣的东西here。它在.Net中RichEdit
背后使用的RichTextBox
的描述。
还解决了你的问题:
var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(POINT)));
Marshal.StructureToPtr(new POINT(), ptr, false);
SendMessage(this.richTextBox1.Handle, EM_GETSCROLLPOS, IntPtr.Zero, ptr);
var point = (POINT)Marshal.PtrToStructure(ptr, typeof(POINT));
Marshal.FreeHGlobal(ptr);
其中:
EM_GETSCROLLPOS = WM_USER + 221
来自pinvoke.net的POINT
结构。