从字符索引确定逻辑行 (Winforms文本框)

7
如果我在一个WordWrap为true的TextBox中调用textBox.GetLineFromCharIndex(int),它将返回用户所见的行索引(换行的行数计为多行),而不是根据换行符的行。 有没有人知道如何解决从字符索引找到逻辑行而不是显示行的问题?
第一行延伸到     // <- 换行
这里。              // <- 逻辑行1,GetLineFromCharIndex返回行2
这是第二行。      // <- 逻辑行2,GetLineFromCharIndex返回行3
5个回答

2

查找在您的字符索引之前整个文本中换行符的出现次数。

可能首先需要对文本框中的文本进行子字符串处理,直到达到您的字符索引。使用Split函数查找换行符并计算结果。

另外,循环解决方案将使用Index函数,并计算在您的字符索引之前发现了多少个换行符。


我最终选择了循环解决方案。谢谢! - Zach Johnson

1
我使用这段代码在点击RichTextBox时找到行索引:
string sub = richtextbox1.Text.Substring(0, richtextbox1.SelectionStart);
int index = sub.Count(f => f == '\n');

1

我倾向于认为这种解决方案比循环查找换行符要快。您需要使用“SendMessage”将消息“EM_LINEFROMCHAR”发送到文本框。

[DllImport("User32.DLL")]
public static extern int SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);

public const int EM_LINEFROMCHAR = 0xC9;
int noLines = SendMessage(TextBox.Handle, EM_LINEFROMCHAR, TextBox.TextLength, 0);

通过这种方式,您可以根据字符串长度找出最后一行...这将告诉您使用的逻辑行数...

希望能有所帮助,


@Zach:哦……我没意识到那个……说实话,在工作中很少用到那种方法……干得好…… - t0mm13b

0

以下方法适用于我 - 没有明显的性能损失

this.WordWrap = false;
int lineIndex = this.GetLineFromCharIndex(this.SelectionStart);
string lineText = this.Lines[lineIndex];
this.WordWrap = true;

很遗憾,对于我来说,5000行的文本需要大约一秒钟的“闪烁”/重绘。 - Tony Delroy

0
你也可以使用字符串扩展方法和Func、Lambda表达式或任何其他方法,如果你不想编写循环。
long lineNumber = textBox.Text.Substring(0, textBox.SelectionStart).LongCount(chr => chr == '\r');

这将返回基于 0 的行编号。


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