winforms - 如何实现ScintillaNET列编辑模式

标签 winforms textbox scintilla scintillanet

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

notepad++一样alt+鼠标拖动来选择文本 block ,或者拉下一个长垂直光标并按某个键在光标上方的每一行插入一个字符。

我尝试了 ScintillaNET,但它 not suppor the column-modet对于插入,只能删除选定的文本 block

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

notepad++ ScintillaNET

最佳答案

我找到了解决的方法。仍在使用 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 SelWrap{Begin=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);
    }
};

//...

关于winforms - 如何实现ScintillaNET列编辑模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35954882/

相关文章:

c# - 在 WPF 中以编程方式为动态组合框中的动态文本框设置数据绑定(bind)

c# - 从 View 模型将焦点设置在 WPF 中的 TextBox

c++ - pygtkscintilla 自动缩进

c# - 使用 async/await 时防止 winforms UI 阻塞

c# - 设计模式以适应处理 Winform 功能的两种不同方式

c# - 如何在应用程序启动时立即显示光标?

javascript - 如何从 Chrome 扩展调用 OnBlur 方法

winforms - 在 WinForms 中使用 XAML

c++ - Scintilla 词法分析器帮助。尝试保存特定线路信息以备后用

c++ - wxWidgets/wxStyledTextCtrl - 双击时突出显示所有事件