我正在使用FastColoredTextBox
项目,无法弄清楚当鼠标触发事件被触发时鼠标悬停在哪个单词(或字符位置)上(所以我可以显示关于单词的提示)用法)。我找到了一个类似的SO question,但它只处理RichTextBox
,方便地使用GetCharIndexFromPosition
方法。
这可能是一个很长的镜头,但是这里的任何人都以这种方式与FastColoredTextBox
合作并且可以提供帮助吗?
否则,在FastColoredTextBox
的源代码中窥探我实际上无法告诉它用于绘制文本的控件。虽然我怀疑它的类声明
public partial class FastColoredTextBox : UserControl, ISupportInitialize
它可能会自己做。我认为最好的办法是查看RickTextBox
如何实现GetCharIndexFromPosition
并尝试使用FastColoredTextBox
重新创建MouseClick
。
有关如何处理此问题的任何建议吗?
编辑:在FCTB的源代码中,我从public Place PointToPlace(Point point)
事件开始,因为当用户单击文本时此事件会移动光标,因此它必须在某个点上从老鼠。在事件处理程序中,我找到了方法composer require --prefer-dist yiisoft/yii2-authclient "*"
。看起来这可能是我想要的。
如果这导致我找到解决方案,我会发布问题的答案。
答案 0 :(得分:2)
PointToPlace
会返回Place
,告诉您行和字符索引(在行上)。
PointToPosition
返回绝对字符位置
我测试了这个(在vb.net ...中),它没有经过优化,但是第一次开始并且到目前为止工作:
Private Sub test_MouseMove(snd As Object, e As MouseEventArgs)
Dim p As Integer = Me.fctb.PointToPosition(Me.fctb.PointToClient(Windows.Forms.Cursor.Position))
' display letter
Dim ch As String = ""
If p < Me.fctb.Text.Length Then ch = Me.fctb.Text.ToCharArray()(p)
Me.Label1.Text = ch
' display word
Me.Label2.Text = GetWord(Me.fctb, p)
End Sub
Private Function GetWord(ct As FastColoredTextBoxNS.FastColoredTextBox, p As Integer) As String
Dim sb As New StringBuilder(ct.Text)
If sb.Length = 0 OrElse p = sb.Length Then Return ""
If Not Regex.IsMatch(sb.Chars(p).ToString, "^\w$") Then Return sb.Chars(p).ToString
Dim n1 As Integer = p
While n1 > 0 AndAlso Regex.IsMatch(sb.Chars(n1 - 1).ToString, "^\w$")
n1 -= 1
End While
Dim n2 As Integer = p
While n2 < sb.Length AndAlso Regex.IsMatch(sb.Chars(n2 + 1).ToString, "^\w$")
n2 += 1
End While
Return sb.ToString.Substring(n1, n2 - n1 + 1)
End Function
C#代码:
private void test_MouseMove(object snd, MouseEventArgs e) {
var p = fctb.PointToPosition(fctb.PointToClient(Windows.Forms.Cursor.Position));
// display letter
var ch = "";
if (p < fctb.Text.Length) {
ch = fctb.Text[p].ToString();
}
Label1.Text = ch;
// display word
Label2.Text = GetWord(fctb, p);
}
private string GetWord(FastColoredTextBoxNS.FastColoredTextBox ct, int p) {
var sb = new StringBuilder(ct.Text);
if (sb.Length == 0 || p == sb.Length) return "";
if (!Regex.IsMatch(sb[p].ToString(), @"^\w$")) return sb[p].ToString();
var n1 = p;
while (n1 > 0 && Regex.IsMatch(sb[n1 - 1].ToString(), @"^\w$")) {
n1 -= 1;
}
var n2 = p;
while (n2 < sb.Length && Regex.IsMatch(sb[n2 + 1].ToString(), @"^\w$")) {
n2 += 1;
}
return sb.ToString().Substring(n1, n2 - n1 + 1);
}
答案 1 :(得分:0)
好吧,我已经确定MouseHover
事件不是我希望显示单词信息的方式。它在我想要时不会触发,我想我将使用键盘快捷键来显示我想要的信息。
虽然在我退出之前,我确实在C#中提出了这个部分解决方案。它有一些错误。当将鼠标悬停在文本的最后一个单词上时,有时会出现问题。我觉得我混合char
和String
会导致一些我没有追查的深奥问题。
private void fctbEditor_MouseHover(object sender, EventArgs e)
{
int charIndex = fctbEditor.PointToPosition(fctbEditor.PointToClient(Cursor.Position));
if (charIndex != fctbEditor.Text.Length && fctbEditor.Text.Length > 0 && fctbEditor.Text[charIndex] != ' ')
{
String hoverWord = GetWord(charIndex);
// Do with the word as you please
Console.Out.WriteLine(" - Index: " + charIndex + " Char[" + fctbEditor.Text[charIndex].ToString() + "] Word[" + hoverWord + "]");
}
}
private String GetWord(int charPos)
{
int revPos = charPos;
char curChar = fctbEditor.Text[revPos];
while (curChar != ' ' && curChar != '\n' && revPos > 0)
{
revPos -= 1;
curChar = fctbEditor.Text[revPos];
}
int forPos = charPos;
curChar = fctbEditor.Text[forPos];
while(curChar != ' ' && curChar != '\n' && forPos < fctbEditor.Text.Length)
{
forPos += 1;
curChar = fctbEditor.Text[forPos];
}
return fctbEditor.Text.Substring(revPos + 1, forPos - revPos - 1);
}