Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> VirtualStringTree Drag&Drop 
V
    Опции темы
former
Дата 24.2.2010, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



Внимательно читал статью Quadr0, искал на форуме и в инете, но так решение своего вопроса и не нашел. Опыт работы с VST у меня не большой, поэтому надеюсь на вашу помощь форумчане.
Что бы было понятно в чем проблема, в качестве примера буду использовать пользователей, компьютеры и права.
Итак. Имеется три дерева VST.
Первое дерево имеет следующую структуру (3-уровня):
Пользователь_1 (корневой элемент, грузится из таблицы Users БД)
 |-Компьютеры (создается для каждого пользователя)
   |-Компьютер_1 (грузится из таблицы-связи UserComp БД)
   |-Компьютер_2 (грузится из таблицы-связи UserComp БД)
   |-Компьютер_3 (грузится из таблицы-связи UserComp БД)
   ...
   |-Компьютер_N (грузится из таблицы-связи UserComp БД)
 |-Права (создается для каждого пользователя)
   |-Право_1 (грузится из таблицы-связи UserPermiss БД)
   |-Право_2 (грузится из таблицы-связи UserPermiss БД)
   |-Право_3 (грузится из таблицы-связи UserPermiss БД)
   ...
   |-Право_N (грузится из таблицы-связи UserPermiss БД)
...
Пользователь_N (корневой элемент, грузится из таблицы Users БД)

Второе дерево имеет следующую структуру (1-уровень):
Компьютер_1 (корневой элемент, грузится из таблицы Computers БД)
Компьютер_2 (корневой элемент, грузится из таблицы Computers БД)
...
Компьютер_N (корневой элемент, грузится из таблицы Computers БД)

Третье дерево имеет следующую структуру (1-уровень):
Право_1 (корневой элемент, грузится из таблицы Permissions БД)
Право_2 (корневой элемент, грузится из таблицы Permissions БД)
...
Право_N (корневой элемент, грузится из таблицы Permissions БД)

Вопросов по построению и изменению элементов дерева не возникает, равно как и чтению/записи в БД.
Единственно что не знаю как реализовать, так это копирование элементов из деревьев 2 и 3 в 1 с помощью Drag&Drop, которое должно осуществляться следующим образом:
- при переносе в уровень "Пользователь" (1-й), пункт должен записываться дочерним элементом уровня "Компьютеры" (2-й) или "Права" (2-й), в зависимости от дерева-источника.
- при переносе в уровни "Компьютеры" (2-й) или "Права" (2-й), независимо от дерева-источника, пункт должен записываться дочерним элементом соответствующего уровня "Компьютеры" (2-й) или "Права" (2-й), в зависимости от дерева-источника.

Проще говоря, что бы компьютеры попадали в "Компьютеры," а права в "Права", соответствующего пользователя.
Как это реализовать?

Запись элемента имеет следующий вид:
Код

type
  PVSTRecord = ^TVSTRecord;
  TVSTRecord = record
    El_ID: integer; //ID записи в БД
    El_ParentID: integer; //ID родителя
    El_Name: string; //Название элемента
end;


Это сообщение отредактировал(а) former - 24.2.2010, 16:52


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
former
Дата 25.2.2010, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



up


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
kami
Дата 25.2.2010, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Я правильно понял, что в первом дереве:
в уровне 1 - только пользователи
в уровне 2 - "корневой" элемент "компьютеры" или "права", являющийся просто заголовком
в уровне 3 - имя компьютера или имя права.

Кроме уровня вложенности есть ли отличия? К примеру - нельзя ли в TVSTRecord внести поле elType=(etUser, etRootPC, etRootRights, etPC, etRight) ?
PM MAIL WWW   Вверх
former
Дата 25.2.2010, 22:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



Цитата(kami @  25.2.2010,  20:28 Найти цитируемый пост)
Я правильно понял

kami, именно так.
Цитата(kami @  25.2.2010,  20:28 Найти цитируемый пост)

Кроме уровня вложенности есть ли отличия? К примеру - нельзя ли в TVSTRecord внести поле elType=(etUser, etRootPC, etRootRights, etPC, etRight) ? 

Я об этом варианте думал, правда в другом формате (U,C,P,UC,UP), но проблема моя состоит в самой реализации событий OnDragDrop и OnDragOver. Если я правильно понял, то в этих событиях необходимо читать данные DropTargetNode. Так?



--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
kami
Дата 26.2.2010, 00:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(former @  25.2.2010,  22:12 Найти цитируемый пост)
Я об этом варианте думал, правда в другом формате (U,C,P,UC,UP)

Да без разницы как, главное - мы друг друга поняли smile

Цитата(former @  25.2.2010,  22:12 Найти цитируемый пост)
Если я правильно понял, то в этих событиях необходимо читать данные DropTargetNode. Так?

В статье Quadro, пункт 3.0 этот процесс очень хорошо описан. Если вкратце - то да, + Source.GetSortedSelection. Главное - не перепутать типы NodeData из дерева 2 и 3 smile 

Это сообщение отредактировал(а) kami - 26.2.2010, 00:36
PM MAIL WWW   Вверх
former
Дата 28.2.2010, 22:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



kami, не понимаю, где определять, куда нужно добавить нод.


Присоединённый файл ( Кол-во скачиваний: 20 )
Присоединённый файл  VT_Test.zip 29,19 Kb


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
kami
Дата 1.3.2010, 01:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Код я написал. Правда, я видимо пользуюсь более новой версией VT - не совпали типы событий OnGetText, пришлось их чуть подправить, чтобы запускались у меня на компьютере. Думаю, большого труда исправить обратно не составит.

Кстати, зря проигнорировал мое предложение сделать ElType - перечисляемым (или как они называются, не помню) типом. Определять тип строкой - для этого должны быть очень веские основания, т.к. обработка строк занимает гораздо больше времени, уменьшается удобочитаемость, приходится задействовать кучу if вместо одного case и так далее...

Собственно, код во вложении, с достаточно подробными комментариями...
Объявлено событие OnDragOver; в дереве компьютеров DragMode=dmAutomatic, DragType=dtOLE. Вроде всё, но лучше посмотреть самому.

Это сообщение отредактировал(а) kami - 1.3.2010, 01:42

Присоединённый файл ( Кол-во скачиваний: 22 )
Присоединённый файл  VT_Test.zip 7,88 Kb
PM MAIL WWW   Вверх
former
Дата 1.3.2010, 02:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



Цитата(kami @  1.3.2010,  01:35 Найти цитируемый пост)
Правда, я видимо пользуюсь более новой версией VT - не совпали типы событий OnGetText, пришлось их чуть подправить, чтобы запускались у меня на компьютере.

У меня 4.8.6. Вроде бы последняя.
Цитата(kami @  1.3.2010,  01:35 Найти цитируемый пост)
Кстати, зря проигнорировал мое предложение сделать ElType - перечисляемым (или как они называются, не помню) типом. Определять тип строкой - для этого должны быть очень веские основания, т.к. обработка строк занимает гораздо больше времени, уменьшается удобочитаемость, приходится задействовать кучу if вместо одного case и так далее...

Согласен. Поправлю.
Цитата(kami @  1.3.2010,  01:35 Найти цитируемый пост)
Собственно, код во вложении, с достаточно подробными комментариями...
Объявлено событие OnDragOver; в дереве компьютеров DragMode=dmAutomatic, DragType=dtOLE. Вроде всё, но лучше посмотреть самому.

Большое спасибо за помощь (+). Буду разбираться. Если появятся вопросы, отпишу.


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
former
Дата 2.3.2010, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



kami, остается непонятным, где нужно осуществлять запись в БД при перетаскивании. Понимаю, что до перетаскивания, что бы в случае ошибки можно было откатить транзакцию и отменить копирование записи.

Решил прислушаться к твоим комментариям. Кое что уже поправил. Теперь ломаю голову над тем, как разрешить копировать нод только в ту ветку, где он должен находиться.

Это сообщение отредактировал(а) former - 2.3.2010, 19:38


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
kami
Дата 2.3.2010, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Вот по поводу БД - не ко мне, вообще не соображаю в них.
Цитата(former @  2.3.2010,  19:32 Найти цитируемый пост)
Понимаю, что до перетаскивания, что бы в случае ошибки можно было откатить транзакцию и отменить копирование записи.

Тогда - до 
Код

TargetNode := Sender.InsertNode(TargetNode, amAddChildLast);

так как именно он добавляет нод к главному списку.
А почему должна возникнуть ошибка?
PM MAIL WWW   Вверх
former
Дата 2.3.2010, 19:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



Цитата(kami @  2.3.2010,  19:39 Найти цитируемый пост)
А почему должна возникнуть ошибка? 

Вот как я рассуждаю.
Есть три таблицы в БД: Пользователи, Компьютеры и Компьютеры пользователей.
Дерево пользователей и их компьютеров грузится в первый VST, а компьютеров - во второй VST.
После того как выполнен Drop (при попытке добавить компьютер пользователю), должна быть выполнена попытка записи в таблицу Компьютеры пользователей и только после этого выполнено изменение в дереве пользователей.
Ошибка может возникнуть при записи в БД в нескольких случаях:
- пропало соединение с сервером (для сетевой БД)
- отсутствуют права на определенную операцию с БД
- данный компьютер уже присутствует в списке пользователя
ну и т.п.

Добавлено через 4 минуты и 40 секунд
У набора данных UCompDataS (Компьютеры пользователей) есть событие AfterPost (действия после записи) вот в нем и нужно давать разрешение на вставку нода в дерево, а в событии OnPostError - наоборот запрещать.


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
kami
Дата 2.3.2010, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(former @  2.3.2010,  19:52 Найти цитируемый пост)
 есть событие AfterPost (действия после записи) вот в нем и нужно давать разрешение на вставку нода в дерево, а в событии OnPostError - наоборот запрещать.

Это синхронные или асинхронные события?
В смысле, если добавление данных осуществить в OnDragDrop - что будет раньше - одно из этих событий, или end DragDrop?
Цитата(former @  2.3.2010,  19:52 Найти цитируемый пост)
- пропало соединение с сервером (для сетевой БД)- отсутствуют права на определенную операцию с БД- данный компьютер уже присутствует в списке пользователя

Первые 2 - согласен, есть такое дело.
Третье можно (и имхо, нужно ибо будет в тыщу раз быстрее, чем операция с БД) обрабатывать непосредственно при добавлении.
PM MAIL WWW   Вверх
former
Дата 2.3.2010, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



Цитата(kami @  2.3.2010,  21:32 Найти цитируемый пост)
Это синхронные или асинхронные события?
В смысле, если добавление данных осуществить в OnDragDrop - что будет раньше - одно из этих событий, или end DragDrop?

Механизм следующий:
В тот момент, когда бросают нод при переносе, осуществляется попытка записи данных в БД (вызывается метод Post). В случае ошибки возникает событие OnPostError. Если запись выполнена успешно, то выполняется AfterPost. Вот именно в AfterPost необходимо добавлять этот нод в дерево.

Таким образом независимо от ошибки (перечисленных ранее) при сохранении данных в БД, нод будет добавлен только в случае успешного Post.

Т.е. может быть код DragDrop перенесен в AfterPost?


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
kami
Дата 2.3.2010, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(former @  2.3.2010,  21:49 Найти цитируемый пост)
Т.е. может быть код DragDrop перенесен в AfterPost?

Да без проблем. Нужно только где-то сохранить SourceNodeData и TargetNode ( то, которое до vt.InsertNode).

И все-таки ты не ответил на мой вопрос (это уже чисто из любопытства) - если добавлять элемент в БД из события OnDragDrop, что будет раньше - вызовется событие OnAfterPost или же до него будет выход из OnDragDrop ?

Добавлено через 2 минуты и 20 секунд
Таким образом - убираем из кода vt.InsertNode и всё после него.
Сохраняем указанные выше параметры.
Вместо убранного - добавляем данные в базу данных.
В OnAfterPost пишем всё, что удалили из OnDragDrop.
PM MAIL WWW   Вверх
former
Дата 2.3.2010, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



Сначала OnAfterPost потом выход из OnDragDrop.


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
kami
Дата 2.3.2010, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(former @  2.3.2010,  22:04 Найти цитируемый пост)
Сначала OnAfterPost потом выход из OnDragDrop.

Вот и чудненько. Тогда всё сказанное из предыдущего поста - в силе.
PM MAIL WWW   Вверх
kami
Дата 3.3.2010, 00:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(former @  2.3.2010,  19:32 Найти цитируемый пост)
Теперь ломаю голову над тем, как разрешить копировать нод только в ту ветку, где он должен находиться.

Не вижу проблемы.
Это реализуется в OnDragOver.
Примерный алгоритм (возможны варианты, код будет очень похож на OnDragDrop). Для простоты считаем, что выделить и перебросить несколько элементов сразу невозможно.

берем DropTargetNode и соответствующий ему TargetNodeData
берем SourceNodes[0] (если есть, конечно) и соответствующий ему SourceNodeData
Смотрим на Mode: TDropMode
Код

Если Mode=dmOnNode, то 
Accept:=(TargetNodeData.ElType='Пользователь') или 
    (TargetNodeData.ElType='КомпьютерЫ' и SourceNodeData.ElType='КомпьютеР') или 
    (TargetNodeData.ElType='ПравА' и SourceNodeData.ElType='ПравО').

Это гарантирует, что "внутрь" нода, над которым висит на данный момент курсор попадут только "свои" данные. Причем - если мы над "пользователем", то разрешаем всё. Если внутри какого-нибудь из списков (т.е. над элементом 3-го уровня) - то "так низзя".

Иначе (Mode<>dmOnNode) - пользователь пытается воткнуть новый нод между элементами. По логике это возможно только в том случае, если мы пытаемся воткнуться между элементами третьего уровня (т.е. компьютер - между компами, уже находящимися в списке "Компьютеры" этого пользователя, для прав - то же самое). Тут гораздо проще 
Код

Accept:=SourceNodeData.ElType=TargetNodeData.ElType. 
Всё, нет проблемы. smile 

Это сообщение отредактировал(а) kami - 3.3.2010, 00:51
PM MAIL WWW   Вверх
former
Дата 3.3.2010, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



kami, реализовал!

Переменные сделал глобальными.
Код

var
  MainForm: TMainForm;
  SourceNodes: TNodeArray;
  TargetNode: PVirtualNode;
  SourceNodeData: PUVSTRecord;
  TargetNodeData: PUVSTRecord;
  CopiedNodeData: PUVSTRecord;


OnDragDrop:
Код

procedure TMainForm.UsersVTDragDrop(Sender: TBaseVirtualTree; Source: TObject;
  DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState;
  Pt: TPoint; var Effect: Integer; Mode: TDropMode);
function GetNeededNode(DropNode: PVirtualNode; DropElType: TRecType): PVirtualNode;
begin
  Result := DropNode;
  while Sender.GetNodeLevel(Result) <> 0 do
    Result := Result.Parent;
  case DropElType of
    etPC: Result := Sender.GetFirstChild(Result);
    etRight:
      begin
        Result := Sender.GetFirstChild(Result);
        Result := Sender.GetNextSibling(Result);
      end;
    else
      Result := nil;
  end;
end;
begin
  Effect := DROPEFFECT_COPY;
  if not (Source is TBaseVirtualTree) then
    Exit;
  SourceNodes := TBaseVirtualTree(Source).GetSortedSelection(True);
  SourceNodeData := TBaseVirtualTree(Source).GetNodeData(SourceNodes[0]);
  if Assigned(SourceNodeData) then
  begin
    TargetNode := GetNeededNode(Sender.DropTargetNode, SourceNodeData.ElType);
    TargetNodeData:=Sender.GetNodeData(TargetNode);
    AddUserComp; //Запись данных в БД (см. ниже)
  end;
end;


OnDragOver:
Код

procedure TMainForm.UsersVTDragOver(Sender: TBaseVirtualTree;
  Source: TObject; Shift: TShiftState; State: TDragState; Pt: TPoint;
  Mode: TDropMode; var Effect: Integer; var Accept: Boolean);
var SourceNodesO: TNodeArray;
    TargetNodeO: PVirtualNode;
    SourceNodeDataO,TargetNodeDataO: PUVSTRecord;
begin
  if Source is TBaseVirtualTree then
  begin
    SourceNodesO := TBaseVirtualTree(Source).GetSortedSelection(True);
    SourceNodeDataO := TBaseVirtualTree(Source).GetNodeData(SourceNodesO[0]);
    if Assigned(SourceNodeDataO) then
    begin
      TargetNodeO:=Sender.DropTargetNode;
      TargetNodeDataO:=Sender.GetNodeData(TargetNodeO);
      if Assigned(TargetNodeDataO) then
      begin
        if Mode = dmOnNode then
        begin
          Accept:=(TargetNodeDataO.ElType = etUser) or
                ((TargetNodeDataO.ElType = etRootPC) and (SourceNodeDataO.ElType = etPC)) or
                ((TargetNodeDataO.ElType = etRootRights) and (SourceNodeDataO.ElType = etRight));

        end
        else Accept:=(SourceNodeDataO.ElType = TargetNodeDataO.ElType);
      end;
    end;
  end
  else Accept:=False;
end;


Запись данных в БД:
Код

procedure TMainForm.AddUserComp;
begin
  with UCompDataS do
  begin
    Append;
    FieldByName('SUSERID').AsInteger:=TargetNodeData.ElParentID;
    FieldByName('SCOMPUTERID').AsInteger:=SourceNodeData.ElID;
    Post;
  end;
end;


Добавление нода в дерево, если запись в БД успешна:
Код

procedure TMainForm.UCompDataSAfterPost(DataSet: TDataSet);
begin
  TargetNode := UsersVT.InsertNode(TargetNode, amAddChildLast);
  CopiedNodeData := UsersVT.GetNodeData(TargetNode);
  CopiedNodeData^ := SourceNodeData^;
end;


Вот только не понятно, что будет, если изменится количество нодов во втором уровне.


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
kami
Дата 3.3.2010, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(former @  3.3.2010,  16:11 Найти цитируемый пост)
Вот только не понятно, что будет, если изменится количество нодов во втором уровне.

А ничего страшного не будет smile
Добавить новые типы в TElType и добавить "свои" условия в 
Цитата(former @  3.3.2010,  16:11 Найти цитируемый пост)
          
Accept:=(TargetNodeDataO.ElType = etUser) or  
                ((TargetNodeDataO.ElType = etRootPC) and (SourceNodeDataO.ElType = etPC)) or
                ((TargetNodeDataO.ElType = etRootRights) and (SourceNodeDataO.ElType = etRight));

 по аналогии с уже добавленными.
PM MAIL WWW   Вверх
former
Дата 3.3.2010, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



Я имел виду в функции GetNeededNode.
Вот на этом участке:
Код

case DropElType of
    etPC: Result := Sender.GetFirstChild(Result);
    etRight:
      begin
        Result := Sender.GetFirstChild(Result);
        Result := Sender.GetNextSibling(Result);
      end;
    else
      Result := nil;
  end;


Или с каждым новым нодом во 2-м уровне будет добавляться еще одна строка
Код

Result := Sender.GetNextSibling(Result);



--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
kami
Дата 3.3.2010, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(former @  3.3.2010,  19:15 Найти цитируемый пост)
Или с каждым новым нодом во 2-м уровне будет добавляться еще одна строка

Это было бы неоптимально, т.к. может измениться не только количество, но и порядок их следования.
Ну, давай подойдем к этой задаче так:

Код

function GetNeededNode(DropNode: PVirtualNode; DropElType: TRecType): PVirtualNode;
var
  RootType:TRecType; // тип "корневого" элемента - "КомпьютерЫ", "ПравА" и т.п.
  tmpNodeData:PVST...
begin
  Result := DropNode;
  // находим элемент "Пользователь"
  While Assigned(Result) do
    begin
      tmpNodeData:=Sender.GetNodeData(Result);
      if tmpNodeData.ElType=elUser then
        break;
      Result:=Result.Parent;
    end;
  if not Assigned(Result) then
    exit;
// определяемся с тем, какой из его под-элементов будем считать "корневым" для бросаемых данных.
// тут возможны варианты, например:
  case DropElType of
    etPC: RootType:=etRootPC;
    etRight: RootType:=etRootRight;
  end;
  // теперь мы имеем : в Result - пользователя, "внутрь" которого нужно добавить нод.  
  // в RootType - тип "дитя" пользователя, внутрь которого нужно добавить нод (гы, "Дом, который построил Джек")
  // пробегаем по дочерним элементам пользователя и ищем тот, который соответствует RootType
  Result:=Sender.GetFirstChild(Result);
  While Assigned(Result) do
    begin
      tmpNodeData:=Sender.GetNodeData(Result);
      if tmpNodeData.ElType=RootType then
        break
      else
        Result:=Sender.GetNextSibling(Result);
    end;
end;


Само собой, это только один из возможных вариантов работы. В нем, например, не предусмотрена возможность поиска не только в дочерних элементах первого уровня; мне не нравится то, что здесь пришлось использовать Case, что уже снижает универсальность... но дальше как-то не думается на сегодняшний день...
PM MAIL WWW   Вверх
former
Дата 4.3.2010, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



kami, не думал о том, что бы расширить статью Quadr0?


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
kami
Дата 4.3.2010, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(former @  4.3.2010,  10:11 Найти цитируемый пост)
не думал о том, что бы расширить статью Quadr0?

Нет, а зачем? Там и так всё более чем расписано.
Единственное, что мог бы предложить в статью или околостатьевый материал - процедуру печати, которая не обрезает строки посередине, а действует почти так, как организована печать в Excel.
PM MAIL WWW   Вверх
former
Дата 4.3.2010, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



Цитата(kami @  4.3.2010,  13:35 Найти цитируемый пост)
Единственное, что мог бы предложить в статью или околостатьевый материал - процедуру печати, которая не обрезает строки посередине, а действует почти так, как организована печать в Excel. 

Это было бы интересно! smile 


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
Sed0Y
  Дата 3.4.2010, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 16.1.2009

Репутация: нет
Всего: нет



Добавте лучше статью - пример как строить дерево с БД к типа (многоуровневая):

Код

1 0
  2 1
  3 1
     4 3
     5 3
        6 5
  7 1
  8 1
9 0


а то я уже запарился - никак не могу придумать и найти - плз
PM MAIL ICQ   Вверх
former
Дата 4.4.2010, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



Цитата(Sed0Y @  3.4.2010,  18:48 Найти цитируемый пост)
Добавте лучше статью - пример как строить дерево с БД к типа (многоуровневая):

Sed0Y, а поиском в соответствующем разделе (БД) воспользоваться не пробовал?


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1523 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.