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