Как отключить автоматический пересчет динамического списка при изменении видимости элементов формы?

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

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

Почему происходит обновление динамического списка?

Для начала проанализируем ситуацию с точки зрения механизмов платформы 1С. В управляемом приложении изменение свойства Видимость (Visibility) — это не просто скрытие элемента с экрана. Платформа интерпретирует это как изменение структуры формы. Это влечет за собой полную перекомпоновку (Layout) всей формы на стороне сервера.

Рассмотрим подробнее механику процесса:

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

Выяснив причину, разберем по шагам наиболее эффективные способы решения этой проблемы.

Способ 1. Использование свойства «Доступность» вместо «Видимости»

Это самый простой и рекомендуемый способ. В отличие от Видимости, изменение свойства Доступность (Enabled) не приводит к перестроению Layout всей формы. Элемент остается на своем месте, его размеры не меняются, он просто становится серым (неактивным).

Рассмотрим, как это реализовать:

Вместо скрытия кнопки в контекстном меню или на командной панели, мы просто отключаем возможность ее нажатия. Проанализируем пример кода:


&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
    ТекущиеДанные = Элементы.Список.ТекущиеДанные;
    Если ТекущиеДанные <> Неопределено Тогда
        // Вместо Элементы.КомандаУдалить.Видимость = Ложь
        Элементы.КомандаУдалить.Доступность = (ТекущиеДанные.Статус <> ПредопределенноеЗначение("Перечисление.Статусы.Заблокирован"));
    КонецЕсли;
КонецПроцедуры

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

Способ 2. Проверка возможности выполнения в обработчике команды

Если по требованиям дизайна кнопки должны оставаться визуально активными, но срабатывать только в определенных условиях, мы можем оставить их видимыми всегда. А логику «скрытия» перенести внутрь самой команды.

Посмотрим на пример реализации:

  1. Оставляем кнопку Видимой и Доступной постоянно.
  2. В процедуре-обработчике действия команды добавляем проверку условий.

&НаКлиенте
Процедура ВыполнитьДействие(Команда)
    ТекущиеДанные = Элементы.Список.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    Если Не МожноВыполнятьОперацию(ТекущиеДанные) Тогда
        ПоказатьПредупреждение(, "Для данной строки это действие недоступно!");
        Возврат;
    КонецЕсли;
    
    // Основная логика команды
КонецПроцедуры

Этот метод полностью исключает влияние интерфейсных манипуляций на поведение динамического списка.

Способ 3. Использование обработчика ожидания

Иногда требуется именно скрывать элементы, и делать это нужно при перемещении по строкам списка (в событии ПриАктивизацииСтроки). Прямое изменение видимости в этом событии гарантированно вызывает «фризы» из-за циклического обновления. Мы можем применить хитрость с ПодключитьОбработчикОжидания.

Разберем по шагам, как это работает:

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


&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
    // Откладываем обновление интерфейса на 0.1 - 0.2 секунды
    ПодключитьОбработчикОжидания("ОбновитьВидимостьКоманд", 0.1, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьВидимостьКоманд()
    ТекущиеДанные = Элементы.Список.ТекущиеДанные;
    Если ТекущиеДанные <> Неопределено Тогда
        НоваяВидимость = (ТекущиеДанные.Сумма > 1000);
        Если Элементы.СпецДействие.Видимость <> НоваяВидимость Тогда
             Элементы.СпецДействие.Видимость = НоваяВидимость;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Важный момент: обязательно проверяйте текущее состояние видимости перед установкой нового значения (Если Элементы.СпецДействие.Видимость <> НоваяВидимость). Если свойство уже установлено в нужное значение, повторная установка все равно может спровоцировать пересчет Layout.

Способ 4. Метод перемещения в скрытую группу

Существует продвинутый технический прием, позволяющий «обмануть» механизм Layout. Вместо управления свойством Видимость конкретной кнопки, мы можем создать на форме специальную группу, у которой Видимость изначально установлена в Ложь (на уровне конфигуратора или ПриСозданииНаСервере).

Проанализируем алгоритм:

  1. Создаем на форме группу СкрытоеХранилище (Видимость = Ложь).
  2. Когда кнопку нужно скрыть, мы не меняем ее видимость, а перемещаем ее в эту группу с помощью метода Элементы.Переместить().
  3. Когда кнопку нужно показать, перемещаем ее обратно в основную командную панель.

Этот метод считается более «тяжелым» программно, но в ряде случаев он позволяет избежать принудительного обновления данных в ДинамическомСписке, так как корневая структура видимых элементов меняется менее радикально.

Способ 5. Динамическое изменение текста или картинки кнопки

Если задача стоит в том, чтобы дать пользователю понять, что команда изменилась, попробуйте менять заголовок (Caption) или картинку (Picture) вместо скрытия кнопки целиком. Изменение текста или иконки кнопки не меняет размеры элемента в большинстве случаев и не вызывает перестроения всей формы.

Пример кода:


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

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

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

Применяя эти подходы, вы обеспечите плавную и стабильную работу интерфейса вашего решения на базе 1С:Предприятие 8.3.

← На главную