FastColoredTextbox AutoWordSelection?

时间:2014-01-02 19:20:42

标签: c# .net vb.net winforms user-controls

FastColoredTextbox是一个可以在this url下载的用户控件,它看起来像这样:

enter image description here

它是一个惊人的控件但只能在双击文本时选择一个单词,不能按住鼠标选择更多单词,所以它只选择鼠标指针上的整个当前单词,即使你试图移动鼠标向左或向右光标选择更多文字。

我没有找到解释问题的任何信息,所有官方示例项目都有这个问题。

没有人意味着如何为AutoWordSelection控件制作TextBox等效的默认FastcoloredTextbox,但即使最重要的是:

如何用鼠标选择多个单词?

  

更新:

@ mostruash 回答非常有启发性,但在这段时间里我无法自己进行修改。

我需要C#程序员的大力帮助才能完成这项任务,我对C#的了解非常少,而且我对源代码的修改不起作用(不编译),我回到原来的用户控制源不会最终破坏更多。我讨厌这样说,但这次我需要完成这项工作,这个来源对我来说太过分了。

如果我要求太多,那么可能需要C#开发人员的必要扩展指令,解释如何逐步完成,也许我可以自己执行。

  

更新

解决问题的视频:

https://www.youtube.com/watch?v=Cs2Sh2tMvII

  

更新

另一个演示,我展示FastColoredTextBox 不能做什么,但我想像其他文本编辑器那样做:

enter image description here

4 个答案:

答案 0 :(得分:18)

我检查了项目的源代码。如果发生双击并且调用SelectWord,则会取消拖动。

您可以修改源代码以包含您请求的功能。 (https://github.com/PavelTorgashov/FastColoredTextBox)。在那种情况下:

  • 您必须跟踪以双击开头的选择。
  • 使用SelectWord类和Selection属性标记draggedRange中的所选单词,而不是调用OnMouseMove函数。
  • 您还必须处理取消选择OnMouseMove
  • 中的字词
  • 您还必须在OnMouseMove
  • 中的字词之间选择空格

双击在下面的代码中处理:

            if (!isLineSelect)
            {
                var p = PointToPlace(e.Location);

                if (e.Clicks == 2)
                {
                    mouseIsDrag = false; //Here, drag is cancelled. 
                    mouseIsDragDrop = false;
                    draggedRange = null; //Drag range is nullified

                    SelectWord(p); //SelectWord is called to mark the word
                    return;
                }

                if (Selection.IsEmpty || !Selection.Contains(p) || this[p.iLine].Count <= p.iChar || ReadOnly)
                    OnMouseClickText(e);
                else
                {
                    mouseIsDragDrop = true;
                    mouseIsDrag = false;
                }
            }

编辑

这可能需要做很多工作。所以也许你应该使用另一个工具/库。我没有研究过整个源代码,因此可能会有上面提供的其他步骤。

例如,要跟踪双击,您可以执行以下操作:

  • FastColoredTextbox.cs中定义类变量/属性:bool isDoubleClick
  • true条件下的OnMouseDown中将其设置为if(e.Clicks == 2)。在所有其他条件下将其设置为false
  • OnMouseClickOnMouseUp或其他相关鼠标事件处理程序中将其设置为false。

通过这种方式,您将了解一系列鼠标事件是否已通过双击事件开始。然后你会在OnMouseMove中采取相应的行动,因为这是你(联合国)标记字符或(联合国)标记文字的地方。

最后的注意事项

该项目的作者没有包含任何内联评论或任何其他文档,因此您将逐行学习代码以了解每个函数/部分的作用。

答案 1 :(得分:2)

在班级5276中的行5277和行FastColoredTextBox.cs之间添加以下语句:

SelectWord(p);
mouseIsDrag = true; // here
return;

请注意,实现最终行为需要大量编码。鉴于上述解决方法可能满足您的需求。

答案 2 :(得分:2)

正如@mostruash在他的回答中指出的那样,这是作者取消鼠标拖动的地方。不知道为什么他故意阻止这个功能。只有他知道。

if (e.Clicks == 2)//Line 5270
{
    mouseIsDrag = false;
    mouseIsDragDrop = false;
    draggedRange = null;

    SelectWord(p);
    return;
}

我没有阅读整个代码,我没有理由这样做。我刚刚检查并删除它们。它可以按照您的预期工作。

if (e.Clicks == 2)//Line 5270
{
    //Comment or remove completely.

    //mouseIsDrag = false;
    //mouseIsDragDrop = false;
    //draggedRange = null;

    SelectWord(p);
    return;
}

注意:我不确定这会打破别的东西,我还没有测试过。至少那是有效的。自己测试一下。

答案 3 :(得分:1)

我的解决方案有点蠢,但似乎乍一看似乎有效。

您必须在代码中进行一些更改:

  1. 添加mouseIsWholeWordSelection标志和一个Range变量,该变量可以在双击后存储初始选定范围(最好在第100行之后,我猜):

    private bool mouseIsWholeWordSelection;
    private Range mouseIsWholeWordSelectionBaseRange;
    
  2. 如上所述更改双击事件的选择代码并稍稍扩展(第5222行):

                if (e.Clicks == 2)
                {
                    //mouseIsDrag = false;
                    mouseIsDragDrop = false;
                    mouseIsWholeWordSelection = true;
                    //draggedRange = null;
    
                    SelectWord(p);
                    mouseIsWholeWordSelectionBaseRange = Selection.Clone();
                    return;
                }
    
  3. 添加用于重新创建选择的拖动事件评估(第5566行):

                else if (place != Selection.Start)
            {
                if (mouseIsWholeWordSelection)
                {
                    Selection.BeginUpdate();
                    var oldSelection = Selection.Clone();
                    SelectWord(place);
    
                    if (Selection.End >= mouseIsWholeWordSelectionBaseRange.End)
                    {
                        Selection.Start = (mouseIsWholeWordSelectionBaseRange.Start > Selection.Start) ? mouseIsWholeWordSelectionBaseRange.Start : Selection.Start;
                        Selection.End = mouseIsWholeWordSelectionBaseRange.End;
                    }
                    else if (Selection.Start < mouseIsWholeWordSelectionBaseRange.End)
                    {
                        Selection.Start = new Place(Selection.End.iChar, Selection.End.iLine);
                        Selection.End = mouseIsWholeWordSelectionBaseRange.Start;
                    }
    
                    Selection.EndUpdate();
                    DoCaretVisible();
                    Invalidate();
                }
                else
                {
                    Place oldEnd = Selection.End;
                    Selection.BeginUpdate();
                    if (Selection.ColumnSelectionMode)
                    {
                        Selection.Start = place;
                        Selection.ColumnSelectionMode = true;
                    }
                    else
                        Selection.Start = place;
                    Selection.End = oldEnd;
                    Selection.EndUpdate();
                    DoCaretVisible();
                    Invalidate();
                }
                return;
            }
    
  4. 在isMouseDrag被设置为false的每个地方添加:

    isMouseWholeWordSelection = false;
    
  5. 然后你去。