В процессе разработки сложных интерфейсов на управляемых формах 1С:Предприятие 8.3 программисты часто сталкиваются с особенностью работы стандартных полей ввода: как только пользователь переключает фокус на другой элемент (например, нажимает кнопку или выбирает значение в списке), курсор (каретка) и выделение текста в предыдущем поле мгновенно исчезают. Это стандартное поведение графической подсистемы Windows и платформы 1С, однако в ряде задач — например, при создании текстовых редакторов, конфигураторов или инструментов для работы с контентом — нам необходимо сохранить визуальную индикацию выбранного фрагмента. Разберем подробно, почему это происходит и какими способами можно обойти данное ограничение.
Для начала проанализируем ситуацию с точки зрения архитектуры платформы. В 1С ПолеВвода базируется на стандартных контролах операционной системы. В интерфейсной логике фокус ввода может находиться только на одном элементе одновременно. Чтобы не дезинформировать пользователя, система скрывает каретку в неактивных полях. В других средах разработки (например, Delphi, .NET или Java Swing) у текстовых полей часто есть свойство типа HideSelection, которое позволяет оставить выделение серым или полупрозрачным, даже если фокус ушел. В управляемых формах 1С такое свойство отсутствует.
Многие разработчики пытаются использовать метод УстановитьГраницыВыделения(), надеясь, что он заставит платформу отрисовать выделение. Однако, как показывает практика, этот метод лишь программно фиксирует координаты (начало и длину) выделенного фрагмента в памяти объекта. Визуальная отрисовка этого фрагмента происходит только в том случае, если элемент является активным (ТекущийЭлемент формы). Как только фокус передается другому объекту, платформа прекращает отрисовку "инверсии" текста.
Если задача требует обязательного сохранения выделения (например, вы пишете обработку для поиска и замены текста, где пользователь должен видеть найденный кусок, нажимая кнопки "Далее"), самым надежным способом будет использование Поля HTML документа вместо обычного Поля ввода. Рассмотрим этот метод подробнее.
В HTML-контейнере мы имеем полный контроль над отображением через CSS и JavaScript. Мы можем программно управлять выделением с помощью объекта window.getSelection() и стилизовать его так, чтобы оно не исчезало. Разберем по шагам, как это реализовать:
Строка и видом Поле HTML документа.::selection. Это позволит нам определить цвет фона и текста даже для неактивного окна в некоторых браузерах (движках).Пример программного формирования содержимого для такого поля:
ТекстHTML = "
|<style>
| ::selection { background: #ffb7b7; color: black; }
| .persistent-selection { background-color: yellow; }
|</style>
|<div id='content' contenteditable='true'>Ваш текст здесь...</div>";
ЭтаФорма.Элементы.ПолеHTML.УстановитьТекст(ТекстHTML);
Использование contenteditable превращает HTML-поле в полноценный текстовый редактор, где программное выделение через скрипты будет гораздо стабильнее платформенных методов 1С.
Если использование HTML-поля кажется избыточным, можно воспользоваться советом опытных разработчиков: визуально "подкрашивать" поле или конкретные данные. Рассмотрим ситуацию, когда поле ввода находится в табличной части. Проанализируем возможности оформления: при уходе фокуса мы можем программно изменить цвет фона ячейки или текста, чтобы имитировать наличие внимания к этому элементу.
Для этого удобно использовать УсловноеОформление формы. Процесс выглядит следующим образом:
АктивныйИдентификаторСтроки).ПриАктивизацииСтроки или ПриИзменении поля ввода будем записывать текущее состояние в этот реквизит.Это не создаст эффект выделения конкретных букв внутри слова, но четко укажет пользователю, с каким объектом он работал до перехода к кнопкам управления.
Этот способ считается "хитрым" и подходит для продвинутых интерфейсов. Идея заключается в том, что в момент потери фокуса мы "подменяем" реальное поле ввода статичной картинкой или форматированной строкой.
Разберем алгоритм реализации:
ПолеВвода и ПолеНадписи (вид — Поле декорации).Видимость = Ложь).ПриДеактивизации поля ввода мы считываем границы выделения через ПолучитьГраницыВыделения().ФорматированнаяСтрока, где часть текста, попавшая в границы, выделена другим цветом (свойство ЦветФона).ПолеНадписи, делаем надпись видимой, а само ПолеВвода скрываем.ПриАктивизации) — производим обратную замену.Пример кода для создания форматированной строки с выделением:
// Предположим, ГраницаНачала = 5, ГраницаКонца = 10
Часть1 = Сред(ИсходныйТекст, 1, ГраницаНачала - 1);
ЧастьВыделенная = Сред(ИсходныйТекст, ГраницаНачала, ГраницаКонца - ГраницаНачала);
Часть2 = Сред(ИсходныйТекст, ГраницаКонца);
ТекстДляДекорации = Новый ФорматированнаяСтрока(Часть1,
Новый ФорматированнаяСтрока(ЧастьВыделенная, , , ЦветаСтиля.ФонВыделения),
Часть2);
Элементы.ДекорацияТекст.Заголовок = ТекстДляДекорации;
Важно помнить, что поведение интерфейса в тонком клиенте и веб-клиенте может различаться. В веб-клиенте отрисовкой занимается браузер. Некоторые современные браузеры по умолчанию оставляют "серое" выделение при переходе фокуса (например, если вы выделили текст в поисковой строке и кликнули на свободное место страницы). Однако ядро 1С активно вмешивается в процесс обработки событий DOM, поэтому рассчитывать на стандартное поведение браузера не стоит. Если ваше приложение ориентировано на работу через браузер, использование Варианта 1 (HTML-поле) является практически единственным стабильным решением.
Прежде чем внедрять подобные механизмы, стоит проанализировать ситуацию: не будет ли это вводить пользователя в заблуждение? В классическом интерфейсе отсутствие курсора в поле — это сигнал о том, что нажатие клавиш на клавиатуре не приведет к изменению текста в этом поле. Если вы принудительно оставите курсор (или его имитацию) видимым, пользователь может начать печатать, ожидая ввода в это поле, в то время как фокус будет находиться на другом элементе.
Поэтому, если ваша цель — просто показать, какой фрагмент был выбран, используйте статичную подсветку фона (Вариант 2 или 3), но не пытайтесь имитировать мигающую каретку. Это обеспечит наглядность и сохранит логику работы интерфейса 1С:Предприятие.
Выясним кратко основные моменты:
УстановитьГраницыВыделения() работает в памяти, но не управляет визуализацией без фокуса.Поле HTML документа.УсловноеОформление или динамическое создание ФорматированнойСтроки.Применяя эти подходы, вы сможете создать профессиональный и удобный интерфейс, отвечающий специфическим требованиям ваших бизнес-задач.