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