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