То есть, задача сделать, чтоб было как в нормальном текстовом редакторе, нажимаем 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;
// [...]
}
Достигли последнего возможного символа, перескочили в начало текстового поля.