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