Разработчики на платформе «1С:Предприятие 8.3» часто сталкиваются с неприятным поведением управляемых форм: при попытке программно выполнить изменение заголовков страницы или цвет элемента интерфейса, динамический список, расположенный на этой же форме, внезапно «прыгает». Это происходит потому, что платформа инициирует полную перерисовку формы, возвращая фокус списка к активной строке и сбивая позицию прокрутки, которую выбрал пользователь. Рассмотрим подробнее, почему это происходит и как обойти это ограничение платформы.
Для начала проанализируем ситуацию с точки зрения архитектуры управляемого приложения. Динамический список (ДинамическийСписок) — это сложный объект, который отображает данные порционно. Методы доработки динамических списков показывают, что в нормальном состоянии пользователь может прокрутить список далеко вниз, при этом ТекущаяСтрока (курсор) может оставаться где-то наверху, за пределами видимости.
Когда мы программно меняем свойства элементов формы, такие как ЦветТекстаЗаголовка, Видимость или Доступность напрямую через коллекцию Элементы, платформа 1С расценивает это как изменение метаданных оформления интерфейса. Чтобы отобразить эти изменения, запускается механизм регенерации формы. В этот момент клиентское приложение синхронизируется с сервером, и динамический список принудительно перечитывает состояние. Поскольку позиция скролла (вертикальной прокрутки) не сохраняется программно, платформа просто позиционирует список так, чтобы в области видимости оказалась ТекущаяСтрока. Именно это поведение и раздражает пользователей, так как их «выбрасывает» из того места списка, которое они изучали.
Разберем первый и самый правильный способ изменения текста заголовков. Вместо того чтобы напрямую изменять свойство Заголовок элемента формы, нам следует использовать привязку к реквизиту. Это позволяет платформе обновлять только конкретное значение данных, а не всю структуру интерфейса.
Алгоритм действий следующий:
ТекстЗаголовкаСтраницы с типом Строка.ПутьКДаннымЗаголовка укажем наш новый реквизит.Посмотрим на пример кода:
// Вместо этого (вызывает прыжок списка):
Элементы.ГруппаСтраница1.Заголовок = "Новые данные (5)";
// Используем это (безопасно для списка):
ЭтаФорма.ТекстЗаголовкаСтраницы = "Новые данные (5)";
При таком подходе обновление текста происходит через механизм оповещения об изменении данных, что является «легким» событием и не приводит к перерисовке всей формы.
Зачастую простого изменения текста недостаточно — нужно привлечь внимание пользователя цветом (например, окрасить заголовок в красный при возникновении ошибки). Однако, как мы уже выяснили, программное изменение свойства ЦветТекстаЗаголовка неизбежно приведет к обновлению формы и сбросу позиции в динамическом списке.
Проанализируем обходной путь, который предложили опытные разработчики: использование картинок вместо цвета. Изменение картинки на элементе формы, если оно выполняется правильно, не вызывает «прыжка» списка. Рассмотрим, как это реализовать:
ИндексКартинкиЗаголовка (тип Число) или ПутьККартинкеЗаголовка (тип Строка).ПутьКДаннымКартинки, привязав его к нашему реквизиту.Пример кода для переключения индикации:
&НаКлиенте
Процедура ОбновитьИндикациюПроблем()
Если ОбнаруженыОшибкиНаСервере() Тогда
// Устанавливаем картинку предупреждения
ЭтаФорма.ПутьККартинкеЗаголовка = "БиблиотекаКартинок.Ошибка";
Иначе
// Возвращаем пустую или стандартную картинку
ЭтаФорма.ПутьККартинкеЗаголовка = "";
КонецЕсли;
КонецПроцедуры
Важное замечание: Чтобы этот метод работал стабильно, изменение должно происходить на стороне клиента. Если платформа видит изменение данных, связанных с картинкой, она обновляет только пиктограмму в заголовке, сохраняя состояние всех остальных элементов управления, включая фокус и прокрутку в динамических списках.
Если стандартные возможности заголовков страниц вас не устраивают, можно рассмотреть более радикальный, но гибкий метод — имитацию вкладок. Посмотрим на этот процесс по шагам:
ОтображениеСтраниц = Нет).Поскольку декорации — это отдельные элементы, их обновление через привязку к реквизитам (ПутьКДанным) проходит гораздо «болезненнее» для формы, чем изменение свойств системной группы страниц. Кроме того, в декорациях можно использовать расширенное форматирование текста.
В случаях, когда вкладок много (10 и более) и требования к интерфейсу специфичны, можно использовать ПолеHTMLДокумента. Разберем, почему это эффективно:
Изменение содержимого HTML-поля выполняется на клиенте. Вы можете сформировать строку HTML, содержащую цветные блоки, мигающие индикаторы или любой текст. Поскольку 1С воспринимает изменение текста внутри ПоляHTMLДокумента просто как обновление данных реквизита, никакой регенерации формы не происходит.
Пример формирования индикатора:
&НаКлиенте
Процедура ОбновитьHTMLИндикатор(КоличествоОшибок)
Цвет = ?(КоличествоОшибок > 0, "red", "green");
ТекстHTML = "<html><body style='margin:0; padding:0; overflow:hidden;'>"
+ "<div style='background-color:" + Цвет + "; color:white; text-align:center;'>"
+ "Ошибок: " + КоличествоОшибок
+ "</div></body></html>";
ЭтаФорма.РеквизитПолеHTML = ТекстHTML;
КонецПроцедуры
Мы проанализировали проблему «прыгающих» списков и выяснили, что основной враг стабильного интерфейса — это прямое изменение свойств оформления элементов через Элементы. Чтобы форма оставалась статичной, а пользователи довольными, следует придерживаться следующих правил:
ПутьКДаннымКартинки).Видимость, Доступность).Соблюдение этих рекомендаций позволит создать профессиональный и отзывчивый интерфейс, который не будет мешать работе пользователя с большими объемами данных в динамических списках.