如何实现 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 列编辑模式的主要内容,如果未能解决你的问题,请参考以下文章