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