C#. Windows Forms. Режим замены текста по нажатию клавиши Insert в TextBox.

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

Достигли последнего возможного символа, перескочили в начало текстового поля.

Пример 1 Пример 2
Скачать проекты

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *