如何实现 ScintillaNET 列编辑模式

Posted

技术标签:

【中文标题】如何实现 ScintillaNET 列编辑模式【英文标题】:How to implement ScintillaNET column edit mode 【发布时间】:2016-03-12 07:14:33 【问题描述】:

我需要一个文本编辑器控件来在我的应用程序中进行列编辑。

点赞 notepad++ alt+mouse drag 来选择一个文本块,或者拉下一个长的垂直光标并按一个键在光标上的每一行插入一个字符。

我试过 ScintillaNET 但它 not suppor the column-modet 用于插入,只是可以删除选定的文本块

我需要以下效果(notepad++),但是 ScintillaNET 得到了:

【问题讨论】:

【参考方案1】:

我找到了解决方法。仍在使用 ScintillaNET。

但是编码不够漂亮:)

class SelWrap

    public int Begin  get; set; 
    public int Length  get; set; 


//...

editor.KeyDown += (s, e) =>

    // filter alt we will hold down alt to make vertical selection
    if (e.Alt) return;

    var tb = editor;
    if (tb.Selections.Count < 2) return; // no in column mode

    e.SuppressKeyPress = true; //block input, handle by below code

    //refered from post #5825820
    var input = Utility.GetCharFromKey(e.KeyCode).ToString();
    if (input == "\0")
    
        //SystemSounds.Beep.Play();
        return;
    

    var array = tb.Selections
        .OrderBy(p => p.Start)
        .Select(p => new SelWrapBegin=p.Start, Length=p.End - p.Start )
        .ToArray();

    //do process every caret(or selection)
    for (var i = 0; i < array.Length; i++)
    
        var item = array[i];

        if (item.Length > 0) 
        
            //if has selected text, just clean
            tb.DeleteRange(item.Begin, item.Length);

            for (var j = i + 1; j < array.Length; j++)
            
                array[j].Begin -= item.Length;
            
        

        if (input == "\b") //backspace 
        
            if (item.Length != 0) continue;

            //delete a char before caret
            tb.DeleteRange(item.Begin - 1, 1);

            for (var j = i; j < array.Length; j++)
            
                array[j].Begin--;
            
        
        else //just insert that
        
            tb.InsertText(item.Begin, input);

            for (var j = i; j < array.Length; j++)
            
                array[j].Begin++;
            
        

    

    //restore caret status to keep column mode
    tb.ClearSelections();
    tb.SetSelection(array[0].Begin, array[0].Begin);
    for (var i = 1; i < array.Length; i++)
    
        var item = array[i];
        tb.AddSelection(item.Begin, item.Begin);
    
;

//...

【讨论】:

【参考方案2】:

您需要通过发送所需的消息来打开 Scintilla 矩形选择以初始化矩形选择。例如,

CallScintilla(SCI_SETSELECTIONMODE, SC_SEL_STREAM);
CallScintilla(SCI_SETMOUSESELECTIONRECTANGULARSWITCH, true);
CallScintilla(SCI_SETADDITIONALSELECTIONTYPING, true);  // so you can type in the selection
CallScintilla(SCI_SETMULTIPLESELECTION, false);
// on paste, paste into rectangular selection
CallScintilla(SCI_SETMULTIPASTE, SC_MULTIPASTE_EACH);

之后,它就像 Visual Studio 一样工作,按住 Alt 键并用鼠标拖动以开始矩形选择。

【讨论】:

【参考方案3】:

尝试矩形和多选https://github.com/jacobslusser/ScintillaNET/wiki/Rectangular-and-Multiple-Selections

【讨论】:

以上是关于如何实现 ScintillaNET 列编辑模式的主要内容,如果未能解决你的问题,请参考以下文章

如何读取 ScintillaNET 类的 Text 属性

未触发 ScintillaNet Calltip 事件

ScintillaNET 与 AvalonEdit 为 WPF 应用程序提供脚本接口

从 ScintillaNet 打印内容时打印行号

ScintillaNET 中的缩进和智能缩进

Scinillanet,如何将其文本保存到文件中?