Как изменить заголовок элемента формы 1С без обновления динамического списка и «прыжков» курсора?

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

Разработчики на платформе «1С:Предприятие 8.3» часто сталкиваются с неприятным поведением управляемых форм: при попытке программно выполнить изменение заголовков страницы или цвет элемента интерфейса, динамический список, расположенный на этой же форме, внезапно «прыгает». Это происходит потому, что платформа инициирует полную перерисовку формы, возвращая фокус списка к активной строке и сбивая позицию прокрутки, которую выбрал пользователь. Рассмотрим подробнее, почему это происходит и как обойти это ограничение платформы.

Почему динамический список «прыгает»? Выясним причину

Для начала проанализируем ситуацию с точки зрения архитектуры управляемого приложения. Динамический список (ДинамическийСписок) — это сложный объект, который отображает данные порционно. Методы доработки динамических списков показывают, что в нормальном состоянии пользователь может прокрутить список далеко вниз, при этом ТекущаяСтрока (курсор) может оставаться где-то наверху, за пределами видимости.

Когда мы программно меняем свойства элементов формы, такие как ЦветТекстаЗаголовка, Видимость или Доступность напрямую через коллекцию Элементы, платформа 1С расценивает это как изменение метаданных оформления интерфейса. Чтобы отобразить эти изменения, запускается механизм регенерации формы. В этот момент клиентское приложение синхронизируется с сервером, и динамический список принудительно перечитывает состояние. Поскольку позиция скролла (вертикальной прокрутки) не сохраняется программно, платформа просто позиционирует список так, чтобы в области видимости оказалась ТекущаяСтрока. Именно это поведение и раздражает пользователей, так как их «выбрасывает» из того места списка, которое они изучали.

Решение 1: Использование свойства «ПутьКДаннымЗаголовка»

Разберем первый и самый правильный способ изменения текста заголовков. Вместо того чтобы напрямую изменять свойство Заголовок элемента формы, нам следует использовать привязку к реквизиту. Это позволяет платформе обновлять только конкретное значение данных, а не всю структуру интерфейса.

Алгоритм действий следующий:

  1. Создадим новый реквизит формы, например, ТекстЗаголовкаСтраницы с типом Строка.
  2. В конфигураторе выберем нужный элемент (например, страницу панели) и в свойстве ПутьКДаннымЗаголовка укажем наш новый реквизит.
  3. Теперь для изменения текста на вкладке мы будем менять значение реквизита, а не свойство элемента.

Посмотрим на пример кода:


// Вместо этого (вызывает прыжок списка):
Элементы.ГруппаСтраница1.Заголовок = "Новые данные (5)";

// Используем это (безопасно для списка):
ЭтаФорма.ТекстЗаголовкаСтраницы = "Новые данные (5)";

При таком подходе обновление текста происходит через механизм оповещения об изменении данных, что является «легким» событием и не приводит к перерисовке всей формы.

Решение 2: Визуальная индикация через смену картинок

Зачастую простого изменения текста недостаточно — нужно привлечь внимание пользователя цветом (например, окрасить заголовок в красный при возникновении ошибки). Однако, как мы уже выяснили, программное изменение свойства ЦветТекстаЗаголовка неизбежно приведет к обновлению формы и сбросу позиции в динамическом списке.

Проанализируем обходной путь, который предложили опытные разработчики: использование картинок вместо цвета. Изменение картинки на элементе формы, если оно выполняется правильно, не вызывает «прыжка» списка. Рассмотрим, как это реализовать:

  1. Добавим в конфигурацию или выберем в библиотеке две картинки: например, «СерыйШар» (стандарт) и «КрасныйШар» (внимание).
  2. Создадим реквизит формы ИндексКартинкиЗаголовка (тип Число) или ПутьККартинкеЗаголовка (тип Строка).
  3. У элемента формы (страницы) установим свойство ПутьКДаннымКартинки, привязав его к нашему реквизиту.
  4. В обработчике ожидания или при наступлении события будем менять значение этого реквизита.

Пример кода для переключения индикации:


&НаКлиенте
Процедура ОбновитьИндикациюПроблем()
    Если ОбнаруженыОшибкиНаСервере() Тогда
        // Устанавливаем картинку предупреждения
        ЭтаФорма.ПутьККартинкеЗаголовка = "БиблиотекаКартинок.Ошибка";
    Иначе
        // Возвращаем пустую или стандартную картинку
        ЭтаФорма.ПутьККартинкеЗаголовка = "";
    КонецЕсли;
КонецПроцедуры

Важное замечание: Чтобы этот метод работал стабильно, изменение должно происходить на стороне клиента. Если платформа видит изменение данных, связанных с картинкой, она обновляет только пиктограмму в заголовке, сохраняя состояние всех остальных элементов управления, включая фокус и прокрутку в динамических списках.

Решение 3: Использование «пустых» декораций и группировок

Если стандартные возможности заголовков страниц вас не устраивают, можно рассмотреть более радикальный, но гибкий метод — имитацию вкладок. Посмотрим на этот процесс по шагам:

  1. Отключим отображение стандартных заголовков у группы страниц (свойство ОтображениеСтраниц = Нет).
  2. Над группой страниц разместим горизонтальную группу, в которую добавим обычные декорации (надписи) или кнопки, стилизованные под закладки.
  3. Для индикации проблем будем менять видимость или текст этих декораций.

Поскольку декорации — это отдельные элементы, их обновление через привязку к реквизитам (ПутьКДанным) проходит гораздо «болезненнее» для формы, чем изменение свойств системной группы страниц. Кроме того, в декорациях можно использовать расширенное форматирование текста.

Решение 4: HTML-поле для сложной индикации

В случаях, когда вкладок много (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;
КонецПроцедуры

Подведем итоги

Мы проанализировали проблему «прыгающих» списков и выяснили, что основной враг стабильного интерфейса — это прямое изменение свойств оформления элементов через Элементы. Чтобы форма оставалась статичной, а пользователи довольными, следует придерживаться следующих правил:

Соблюдение этих рекомендаций позволит создать профессиональный и отзывчивый интерфейс, который не будет мешать работе пользователя с большими объемами данных в динамических списках.

← На главную