Управляемая форма 1С 8.2 – работа с деревом значений и таблицей значений. Часть II (Реализация DRAG and DROP)

Управляемая форма 1С 8.2 – работа с деревом значений и таблицей значений. Часть II (Реализация DRAG and DROP)

Эта статья является продолжением статьи «Управляемая форма 1С 8.2 – Работа с деревом значений и таблицей значений. Часть I (Основы)», она будет посвящена реализации механизма Drag and Drop (или проще говоря «Перетаскивания») для ДереваЗначений расположенного на управляемой форме управляемого приложения 1С 8.2

Основная сложность реализации механизма перетаскивания заключается в том, что у строки ДереваЗначений платформа не позволяет просто изменить родителя, т.е. переподчинить строку. Единственный способ это сделать — создать новую строку вместе со всеми подчиненными строками, т.е. полностью скопировать всю ветку дерева вместе со всей иерархией и подчинить ее требуемой строке-родителю, после чего удалить исходную ветку. Данная задача распадается на две подзадачи:
1). Перед перетаскиванием необходимо проверить корректность данной операции, узел дерева нельзя переносить в узлы подчиненные ему самому, т.е. родительский узел нельзя переносить в дочерние, т.к. это приведет к «бесконечной рекурсии» и «падению» платформы. Это реализуется с помощью обработчика события ЭлементДеревоПроверкаПеретаскивания(…)
2). Если перетаскивание возможно, то при помощи обработчика ЭлементДеревоПеретаскивание(…) запускается рекурсивная функция, которая создает новую ветку дерева, подчиненную требуемому родителю, а исходную удаляет.

Обращаю особое внимание на то, что в платформе 8.2 реализован механизм множественного выбора элементов, поэтому вышеуказанные операции необходимо произвести для всех выбранных пользователем элементов.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    // Создание и заполнение "обычного" объекта прикладного типа ДеревоЗначений,
    // который будет отображен на управляемой форме

    // Здесь необходимо расположить код из предыдущей статьи
    // «Работа с деревом значений и таблицей значений. Часть I (Основы)»
    // .....................................................

    // Добавим обработчики и установим свойства
    ЭлементДерево.МножественныйВыбор=Истина;
    ЭлементДерево.РазрешитьПеретаскивание=Истина;
    ЭлементДерево.РазрешитьНачалоПеретаскивания=Истина;
    ЭлементДерево.УстановитьДействие("ПроверкаПеретаскивания",
        "ЭлементДеревоПроверкаПеретаскивания");
    ЭлементДерево.УстановитьДействие("Перетаскивание",
        "ЭлементДеревоПеретаскивание");

КонецПроцедуры

&НаКлиенте
Функция ПроверитьВозможностьПереноса(ПереносимыйЭлемент, Знач НовыйРодитель)

    Пока НЕ НовыйРодитель = Неопределено Цикл
        Если ПереносимыйЭлемент = НовыйРодитель Тогда
            Возврат Ложь;
        КонецЕсли;
        НовыйРодитель = НовыйРодитель.ПолучитьРодителя();
    КонецЦикла;

    Возврат Истина;

КонецФункции

&НаКлиенте
Функция СкопироватьСтрокуДерева(РеквизитДерево, Приемник, Источник)

    Перем НоваяСтрока, ОбратныйИндекс, КолПодчиненныхСтрок;

    // Источник может быть уже перенесен
    // Это происходит если выделены несколько элементов
    // одной и той же ветви дерева на разных уровнях иерархии
    Если Источник = Неопределено Тогда
        Возврат Неопределено;
    КонецЕсли;

    Если Приемник = Неопределено Тогда
        // Добавляем в корень
        НоваяСтрока = РеквизитДерево.ПолучитьЭлементы().Добавить();
    Иначе
        НоваяСтрока = Приемник.ПолучитьЭлементы().Добавить();
    КонецЕсли;

    ЗаполнитьЗначенияСвойств(НоваяСтрока, Источник);

    КолПодчиненныхСтрок = Источник.ПолучитьЭлементы().Количество();
    Для ОбратныйИндекс = 1 По КолПодчиненныхСтрок Цикл
        ПодчиненнаяСтрока = Источник.ПолучитьЭлементы()
            [КолПодчиненныхСтрок - ОбратныйИндекс];
        СкопироватьСтрокуДерева(РеквизитДерево, НоваяСтрока, ПодчиненнаяСтрока);
    КонецЦикла;

    Если Источник.ПолучитьРодителя() = Неопределено Тогда
        РеквизитДерево.ПолучитьЭлементы().Удалить(Источник);
    Иначе
        Источник.ПолучитьРодителя().ПолучитьЭлементы().Удалить(Источник);
    КонецЕсли;

    Возврат НоваяСтрока;

КонецФункции

Если публикация помогла Вам справится с проблемой, решить задачу или расширить свои знания - поддержите автора.

Комментарии:

  1. Steelvan:

    Не нашел, куда перечислять благодарность.

    1. Администратор:

      Пользуйтесь на здоровье ))

Оставить комментарий на Steelvan