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