В процессе разработки на платформе 1С:Предприятие 8.3 (особенно на версиях 8.3.24 и 8.3.25) программисты часто сталкиваются с неприятным визуальным багом: при выборе значения из выпадающего списка в поле типа СписокЗначений флажок (чекбокс) не появляется мгновенно. Для того чтобы «галочка» отобразилась, пользователю приходится совершать лишние действия — закрывать список, кликать в другом месте или нажимать «Показать все». Давайте подробно разберем, почему это происходит, и как мы можем исправить ситуацию программными методами.
Проблема обычно возникает в расширениях конфигурации при попытке реализовать множественный выбор для дополнительного реквизита или фильтра. Рассмотрим технические причины, которые приводят к «зависанию» интерфейса:
ОбработкаВыбора: Если мы устанавливаем СтандартнаяОбработка = Ложь, мы полностью берем управление процессом на себя. Если при этом мы программно меняем данные реквизита, платформа не всегда успевает связать изменение данных с визуальным состоянием выпадающего списка.ОбработкаВыбора, хотя для типа СписокЗначений платформа умеет делать это автоматически при правильной настройке свойств элемента формы.Прежде чем исправлять визуальный баг, давайте приведем в порядок код заполнения списка. Вместо того чтобы обходить выборку запроса в цикле и обращаться к свойствам через точку (что порождает лишние запросы к БД), мы можем использовать метод ЗагрузитьЗначения. Рассмотрим пример правильного заполнения списка в процедуре ПриСозданииНаСервере:
&НаСервере
Процедура ДОСТ_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ЗначенияСвойствОбъектов.Ссылка КАК Ссылка
|ИЗ
| Справочник.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
|ГДЕ
| ЗначенияСвойствОбъектов.Владелец = &Владелец";
// Ищем владельца доп. реквизита
ВладелецИсполнитель = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", "Исполнитель_ВашУникальныйИдентификатор");
Запрос.УстановитьПараметр("Владелец", ВладелецИсполнитель);
// Выгружаем результат напрямую в список выбора элемента формы
РезультатТаблица = Запрос.Выполнить().Выгрузить();
Элементы.Исполнитель.СписокВыбора.ЗагрузитьЗначения(РезультатТаблица.ВыгрузитьКолонку("Ссылка"));
КонецПроцедуры
Использование метода ВыгрузитьКолонку работает значительно быстрее, так как платформа минимизирует количество серверных вызовов и не кэширует каждый объект по отдельности.
Разберем типичную ошибку в обработчике выбора. Если мы используем СписокЗначений, нам не нужно вручную искать индексы и удалять элементы, если наша задача — просто дать пользователю возможность «нащелкать» нужные значения. Проанализируем, как заставить интерфейс обновиться:
&НаКлиенте
Процедура ДОСТ_ИсполнительОбработкаВыбораПосле(Элемент, ВыбранноеЗначение, ДополнительныеДанные, СтандартнаяОбработка)
// Если мы хотим, чтобы галочки работали корректно,
// иногда лучше НЕ устанавливать СтандартнаяОбработка в Ложь.
// Но если логика требует ручного вмешательства:
СтандартнаяОбработка = Ложь;
Список = ЭтаФорма.Исполнитель; // Это наш реквизит формы типа СписокЗначений
ЭлементСписка = Список.НайтиПоЗначению(ВыбранноеЗначение);
Если ЭлементСписка = Неопределено Тогда
Список.Добавить(ВыбранноеЗначение, Строка(ВыбранноеЗначение), Истина);
Иначе
// Если значение уже есть, возможно, пользователь хочет его убрать
Список.Удалить(ЭлементСписка);
КонецЕсли;
// КРИТИЧЕСКИ ВАЖНО для отрисовки в 8.3.25:
// Обычный ОбновитьОтображениеДанных() может не сработать.
// Используем небольшую хитрость с обновлением текста редактирования.
Элементы.Исполнитель.ОбновитьТекстРедактирования();
КонецПроцедуры
Если ни ОбновитьОтображениеДанных(), ни ОбновитьТекстРедактирования() не помогают визуализировать установленную галочку, воспользуемся проверенным методом принудительного обновления потока UI. Мы вызовем процедуру обновления через минимальную задержку. Выясним, как это реализовать:
ОбработкаВыбора в самом конце добавим вызов обработчика.
&НаКлиенте
Процедура ДОСТ_ИсполнительОбработкаВыбораПосле(Элемент, ВыбранноеЗначение, ДополнительныеДанные, СтандартнаяОбработка)
// ... ваша логика выбора ...
// Подключаем однократный обработчик на 0.1 секунды
ПодключитьОбработчикОжидания("ПринудительноОбновитьФорму", 0.1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ПринудительноОбновитьФорму() Экспорт
// Этот вызов заставит платформу перерисовать все активные элементы окна
ЭтаФорма.ОбновитьОтображениеДанных();
КонецПроцедуры
Этот метод кажется избыточным, но в условиях нестабильной работы графического ядра 8.3.25 он является наиболее надежным способом «протолкнуть» обновление флажков в интерфейс.
Проанализируем свойства самого элемента формы (Поля ввода), так как часто причина кроется в настройках в конфигураторе:
Да.СписокЗначений, а внутри него ограничьте тип (например, СправочникСсылка.ЗначенияСвойствОбъектов).Резюмируем: Если вы столкнулись с «невидимыми» галочками, первым делом попробуйте отказаться от СтандартнаяОбработка = Ложь. Если это невозможно — используйте ОбновитьТекстРедактирования() или кратковременный ПодключитьОбработчикОжидания. Это гарантирует, что пользователь увидит результат своего выбора немедленно, что значительно повысит удобство работы с интерфейсом 1С.