То есть, задача сделать, чтоб было как в нормальном текстовом редакторе, нажимаем Ins, и символы перед курсором заменяются на введенные с клавиатуры. Нажимаем еще раз и символы вставляются как обычно.
Элемент управления TextBox
почему-то из коробки это не поддерживает, поддерживает MaskedTextBox
, но и стандартный TextBox
вполне можно допилить. Не знаю, почему на первых строках в поисковике какой-то ужас со StringBuilder
‘ами и чуть ли не вызовом WINAPI, хотя все гораздо проще.
Заводим в форме логическую переменную, которая будет отвечать за то, какой режим ввода сейчас true
— замена, false
— обычная вставка.
bool InsertMode = false;
В обработчик события KeyUp помещаем код, который будет менять флаг, если был нажата клавиша Insert:
private void txtTest_KeyUp(object sender, KeyEventArgs e) { if (e.KeyData == Keys.Insert) { InsertMode = !InsertMode; } }
В обработчике KeyPress
код следующий
private void txtTest_KeyPress(object sender, KeyPressEventArgs e) { //Вытаскиваю объект, который вызвал событие, //чтоб можно было подключить несколько TextBox'ов TextBox tb = (TextBox)sender; //если включен соотв. режим, курсор не в конце текста //и не нажата какая-либо управляющая клавиша //заменим символ перед курсором if (InsertMode && tb.SelectionStart < tb.TextLength && !Char.IsControl(e.KeyChar)) { //выделяем 1 символ перед курсором //область выделения автоматически заменится //символом, введенным с клавиатуры tb.SelectionLength = 1; //если выделен символ перевода строки, значит это конец строки //в multiline TextBox, if (tb.SelectedText == "\r" || tb.SelectedText == "\n") tb.SelectionLength = 0; //не надо ничего //заменять, убираем выделение } }
Вот. Комментарев больше кода 🙂
Можно сделать замену текста по кругу, т.е., когда дошли до последнего возможного символа, начинаем заменять с первого. Может пригодиться, если строка какая-то небольшая, например две цифры секунд, какой-нибудь код, почтовый индекс и т.д.
Надо всего лишь модифицировать первое условие, чтоб исключить проверку на длину строки и добавить проверку на TextBox.MaxLength
if (InsertMode && !Char.IsControl(e.KeyChar)) { //замена по кругу if (tb.SelectionStart == tb.MaxLength) tb.SelectionStart = 0; // [...] }
Достигли последнего возможного символа, перескочили в начало текстового поля.