确定哪个单词鼠标悬停在FastColoredTextBox中?

时间:2016-02-23 21:15:11

标签: c# winforms

我正在使用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 "*"。看起来这可能是我想要的。

如果这导致我找到解决方案,我会发布问题的答案。

2 个答案:

答案 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#中提出了这个部分解决方案。它有一些错误。当将鼠标悬停在文本的最后一个单词上时,有时会出现问题。我觉得我混合charString会导致一些我没有追查的深奥问题。

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);
}