При разработке связанных табличных частей на управляемой форме часто возникает задача: в зависимости от выбранной строки или конкретной колонки в первой таблице необходимо блокировать, делать доступными или скрывать связанные элементы управления (группы, реквизиты, подчиненные таблицы). Однако попытка изменить свойства Доступность или ТолькоПросмотр непосредственно внутри события ПриАктивизацииЯчейки или ПриАктивизацииСтроки нередко приводит к бесконечному циклу или двойному вызову обработчика.
Проанализируем ситуацию, выясним внутренние причины такого поведения платформы 1С и разберем практические способы обхода проблемы.
Рассмотрим подробнее, что происходит на стороне клиента и сервера при изменении свойств формы:
Доступность, Видимость или ТолькоПросмотр у родительской группы или таблицы платформа инициирует обновление визуального дерева элементов формы.ПриАктивизацииЯчейки.Разберем по шагам наиболее распространенный способ решения проблемы: вынос изменения свойств формы из синхронного потока событий активации в отложенный вызов. Это позволяет дождаться, пока платформа завершит позиционирование фокуса на клиенте, и применить визуальные изменения ровно один раз.
Посмотрим на пример реализации с переменной контекста модуля формы:
&НаКлиенте
Перем ДоступностьГруппы;
&НаКлиенте
Процедура ТЧ1ПриАктивизацииЯчейки(Элемент)
// Определяем требуемое состояние в зависимости от текущей колонки
Если Элемент.ТекущийЭлемент.Имя = "ТЧ1ЯчейкаСвойств" Тогда
ДоступностьГруппы = Истина;
Иначе
ДоступностьГруппы = Ложь;
КонецЕсли;
// Подключаем однократный обработчик с минимальной задержкой
ПодключитьОбработчикОжидания("УстановитьДоступностьГруппы", 0.1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура УстановитьДоступностьГруппы() Экспорт
Если Элементы.ГруппаЭлементовТЧ2.Доступность <> ДоступностьГруппы Тогда
Элементы.ГруппаЭлементовТЧ2.Доступность = ДоступностьГруппы;
КонецЕсли;
КонецПроцедуры
Важный момент: параметр Однократно = Истина в методе ПодключитьОбработчикОжидания гарантирует, что даже при нескольких промежуточных срабатываниях процедуры активации фокуса отложенная процедура выполнится только один раз с последним зафиксированным значением переменной.
Если логика формы позволяет не откладывать действие во времени, цикл можно прервать предварительной проверкой текущего значения свойства. Платформа уходит в рекурсию именно тогда, когда свойству повторно присваивается противоположное значение при временном перескоке фокуса на первую колонку.
Посмотрим на пример оптимизированного кода без вызова обработчика ожидания:
&НаКлиенте
Процедура ТЧ1ПриАктивизацииЯчейки(Элемент)
// Вычисляем целевой признак доступности
ТребуемаяДоступность = (Элемент.ТекущийЭлемент.Имя = "ТЧ1ЯчейкаСвойств");
// Меняем свойство ТОЛЬКО в том случае, если оно действительно изменилось
Если Элементы.ГруппаЭлементовТЧ2.Доступность <> ТребуемаяДоступность Тогда
Элементы.ГруппаЭлементовТЧ2.Доступность = ТребуемаяДоступность;
КонецЕсли;
КонецПроцедуры
При таком подходе, когда фокус кратковременно перескакивает и возвращается, повторная установка значения не выполняется, если состояние уже соответствует требуемому, что исключает бесконечный цикл.
Рассмотрим еще один надежный вариант: предотвращение повторного входа в обработчик во время выполнения интерфейсных операций с помощью переменной-флага.
&НаКлиенте
Перем БлокировкаОбработкиАктивизации;
&НаКлиенте
Процедура ТЧ1ПриАктивизацииЯчейки(Элемент)
Если БлокировкаОбработкиАктивизации = Истина Тогда
Возврат;
КонецЕсли;
БлокировкаОбработкиАктивизации = Истина;
Попытка
ТребуемаяДоступность = (Элемент.ТекущийЭлемент.Имя = "ТЧ1ЯчейкаСвойств");
Если Элементы.ГруппаЭлементовТЧ2.Доступность <> ТребуемаяДоступность Тогда
Элементы.ГруппаЭлементовТЧ2.Доступность = ТребуемаяДоступность;
КонецЕсли;
Исключение
БлокировкаОбработкиАктивизации = Ложь;
ВызватьИсключение;
КонецПопытки;
БлокировкаОбработкиАктивизации = Ложь;
КонецПроцедуры
Постоянное изменение доступности всей группы на клиенте создает дополнительную нагрузку на интерфейс. Рассмотрим более легкие и стабильные альтернативы:
ОтображениеСтраниц = Нет. На первой странице расположите элементы в режиме редактирования, на второй — только для чтения. Смена Элементы.ГруппаСтраницы.ТекущаяСтраница выполняется мгновенно и не приводит к сбросу фокуса в активной таблице.ПередНачаломДобавления, ПередНачаломИзменения и ПередУдалением второй таблицы с установкой параметра Отказ = Истина.УсловноеОформление формы. Платформа обрабатывает его нативно, не вызывая паразитных событий перерисовки интерфейса.