Как изменить текст в поле ввода управляемой формы и задать положение каретки?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке интерактивных интерфейсов в управляемом приложении 1С часто возникает задача программного изменения значения поля ввода с одновременным позиционированием курсора (каретки) в определенное место строки или выделением фрагмента текста. Типичный сценарий — автоматическая вставка шаблонов, спецсимволов, гиперссылок или автодополнение текста в процессе набора.

Однако разработчики часто сталкиваются с неприятной особенностью платформы: если сначала изменить значение реквизита формы, а затем сразу вызвать метод УстановитьГраницыВыделения, курсор сбрасывается в начало или конец текста либо выделение вовсе игнорируется.

Разберем причины такого поведения и выясним, как правильно управлять кареткой и текстом на клиенте.

Проблема асинхронного обновления данных на форме

Рассмотрим, что происходит при выполнении следующего фрагмента клиентского кода:


&НаКлиенте
Процедура ВставитьТекст(Команда)
    Объект.ТекстСообщения = "Привет";
    Элементы.ТекстСообщения.УстановитьГраницыВыделения(2, 2);
КонецПроцедуры

На первый взгляд последовательность логична: мы присвоили новое значение реквизиту и сразу попытались поставить каретку после второго символа. Однако визуально каретка оказывается в начале строки. Проанализируем причину:

  1. При изменении реквизита формы Объект.ТекстСообщения данные в модели формы обновляются, но графический элемент интерфейса еще не успел перерисовать свое визуальное состояние.
  2. Метод УстановитьГраницыВыделения применяется к старому содержимому визуального элемента в текущем такте событий.
  3. Платформа в конце такта событий синхронизирует отображение элемента с реквизитом и сбрасывает курсор в позицию по умолчанию.

Рабочее решение: принудительное обновление отображения данных

Чтобы метод позиционирования каретки отработал корректно, необходимо явно заставить платформу синхронизировать визуальное представление элемента управления с измененным реквизитом перед вызовом метода УстановитьГраницыВыделения. Для этого используется глобальный клиентский метод ОбновитьОтображениеДанных.

Посмотрим на корректный пример клиентской процедуры:


&НаКлиенте
Процедура КомандаВставитьТекст(Команда)
    // 1. Изменяем значение связанного реквизита
    Объект.ТекстСообщения = "Привет, мир!";
    
    // 2. Принудительно обновляем визуальное отображение элемента формы
    ОбновитьОтображениеДанных(Элементы.ТекстСообщения);
    
    // 3. Задаем нужную позицию курсора (начало и конец равны позиции каретки)
    Элементы.ТекстСообщения.УстановитьГраницыВыделения(8, 8);
КонецПроцедуры

В этом примере метод ОбновитьОтображениеДанных передает в графический контрол актуальные данные, после чего метод УстановитьГраницыВыделения устанавливает курсор строго после 8-го символа (перед словом «мир!»).

Разница между ОбновитьОтображениеДанных и ОбновитьТекстРедактирования

Разберем подробнее, почему простой вызов метода Элементы.ИмяПоля.ОбновитьТекстРедактирования() не всегда решает задачу:

  1. ОбновитьОтображениеДанных — глобальный метод формы, который обновляет отображение данных для переданного элемента управления (или всех элементов формы, если параметр опущен), синхронизируя графический контрол с данными реквизитов.
  2. ОбновитьТекстРедактирования — метод элемента формы, который работает со свойством ТекстРедактирования, когда пользователь находится в режиме интерактивного редактирования строки. Если свойство элемента ОбновлениеТекстаРедактирования отключено или элемент не в фокусе, этот метод не дает нужного эффекта синхронизации.

Особенности работы с многострочными полями и фокусом ввода

При реализации сложных интерфейсных механизмов обратим внимание на следующие технические нюансы:

  1. Управление фокусом ввода: если команда вызывается по кнопке командной панели, фокус ввода в момент клика смещается на кнопку. Для того чтобы каретка осталась видимой и активной в текстовом поле, полезно перед установкой выделения вернуть активность полю:
    
    ТекущийЭлемент = Элементы.ТекстСообщения;
    ОбновитьОтображениеДанных(Элементы.ТекстСообщения);
    Элементы.ТекстСообщения.УстановитьГраницыВыделения(8, 8);
    
  2. Многострочный режим: для многострочных полей ввода метод УстановитьГраницыВыделения может принимать четыре параметра (строка начала, колонка начала, строка конца, колонка конца), где нумерация строк и колонок начинается с единицы:
    
    // Установка курсора на 2-ю строку, 5-ю колонку
    Элементы.МногострочныйТекст.УстановитьГраницыВыделения(2, 5, 2, 5);
    
  3. Полноценное форматирование (Rich Text): обычное поле ввода предназначено только для плоского текста (тип Строка). Если требуется оформлять гиперссылки, менять начертание или цвета шрифта, следует использовать элемент управления с видом Поле форматированного документа (связанный с типом ФорматированныйДокумент) или Поле HTML документа.
← На главную