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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> VirtualStringTree и иерарх. данные в БД+D'n'D, проблема с Drag'n'drop 
:(
    Опции темы
uandriy
Дата 16.4.2007, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 22.3.2007
Где: Украина, Днепропе ровск

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



Полистал разные форумы, но так и не нашел толком описанных решений использования VST в связке с иерархическими данными, хранящимися в БД. Почитал мануал и статью Quadr0 (как наиболее полный по-моему источник), но и там рассматриваются только примеры, где данные в VST добавляются просто путем изменения RootNodeCount или обычные линейные списки.
Я в процессе изучения написал 3-4 варианта заполнения VST простейшими иерархическими данными (связь типа id-parentid). С этим проблем нет, если нужно, то могу выложить все эти вартианты с описанием. Но вот дошла очередь до Drag'n'drop и начались проблемы.

Нужно организовать возможность перетягивания элементов мышкой для изменения иерархических связей и все это потом сохранять обратно в БД. 
Люди, кто сталкивался с подобным, отзовитесь. Страдают дети, родственники, соседи....  smile 

PM MAIL   Вверх
Bose
Дата 16.4.2007, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

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



Я немного сталкивался. Какие проблемы возникают?

По-моему всё можно описать следующими правилами:
При изменении родителя, меняем ParentID на ID нового родителя. 

Немного сложнее, если надо поменять порядок узлов. У меня для этого заведена отдельная переменная ORDER_ID, и при перетаскивании элемента, ORDER_ID перетаскиваемого узла заменяется на ORDER_ID + или - 1 от ORDER_ID того узла перед или за которым мы бросаем выделенную.  smile 
PM MAIL WWW Skype   Вверх
uandriy
Дата 16.4.2007, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 22.3.2007
Где: Украина, Днепропе ровск

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



Bose, ну, это самый логичный по-моему из вариантов и все это я тоже подразумеваю, но вот КУДА т.е. в какие ивенты все это вписывать -- не могу понять.
То перетаскиваемые элементы пропадают, то ... короче ламерство какое-то.
Сейчас еще перечитаю/перепишу, мож вечером поделюсь впечатлениями.

PM MAIL   Вверх
Bose
Дата 16.4.2007, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

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



В OnDragAllowed пишем:
Код

Allowed:=True;



в OnDragOver пишем следующее:
Код

procedure TfrmClientManager.vtvCatalogs(Sender: TBaseVirtualTree;
  Source: TObject; Shift: TShiftState; State: TDragState; Pt: TPoint;
  Mode: TDropMode; var Effect: Integer; var Accept: Boolean);
var tmpDestNode: PVirtualNode;
begin
  tmpDestNode:=Sender.GetNodeAt(pt.X,pt.Y);
  Accept:=(pt.Y>0) and assigned(tmpDestNode);
end;


в OnDragDrop пишем примерно следующее:
Код

procedure TfrmClientManager.vtvCatalogsDragDrop(Sender: TBaseVirtualTree;
  Source: TObject; DataObject: IDataObject; Formats: TFormatArray;
  Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode);
var
  I: Integer;
//  AttachMode: TVTNodeAttachMode;
  tmpCatObj:TCatalogObject;
  tmpOrderID:variant;
begin
  // GetCatalogObject у меня возвращает ссылку на TCatalogObject для выделенного узла.
  tmpCatObj:=GetCatalogObject(Sender, Sender.DropTargetNode);
  if Length(Formats) > 0 then
  begin
    // OLE drag'n drop
    // If the native tree format is listed then use this and accept the drop, otherwise recject (ignore) it.
    // It is recommend by Microsoft to order available clipboard formats in decreasing detail richness so
    // the first best format which we can accept is usually the best format we can get at all.
    for I := 0 to High(Formats) do
      if Formats[I] = CF_VIRTUALTREE then
      begin

        tmpOrderID:=null;
        case Mode of
          dmAbove:
            begin
              tmpOrderID:=tmpCatObj.ORDER_ID-1;
            end;
          dmOnNode:
            begin
              tmpOrderID:=tmpCatObj.ORDER_ID+1;
            end;
          dmBelow:
            begin
              tmpOrderID:=tmpCatObj.ORDER_ID+1;
            end;
        end;
        // in the case the drop target does an optimized move Effect is set to DROPEFFECT_NONE
        // to indicate this also to the drag source (so the source doesn't need to take any further action)
        try
          dsCatalogs.Edit; // Dataset с данными для дерева
         dsCatalogs.FieldByName('ORDER_ID').Value:=tmpOrderID;
         dsCatalogs.Post;
        except
        end;
          Break;
      end;
  end
  else
  begin
    // VCL drag'n drop, Effects contains by default both move and copy effect suggestion,
    // as usual the application has to find out what operation is finally to do
  end;

end;


Свойства дерева: 
ClipboardFormat:=[Virtual Tree Data]
DragType: dtOle

Как вариант ещё могу посоветовать посмотреть как реализван Drag&Drop в в демках к Dynamic DBTreeView controls 


Это сообщение отредактировал(а) Bose - 16.4.2007, 13:43
PM MAIL WWW Skype   Вверх
uandriy
Дата 16.4.2007, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 22.3.2007
Где: Украина, Днепропе ровск

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



Bose, а если не секрет, то вы как дерево заполняли первоначальными данными?
Я "нашел" след. способы "глобальные":
1 - "На лету": 
 Заполняю через AddChild только корневые элементы (самый верхний уровень), а в событиях OnInitChildren отфильтровываю MemTable, оставляя только дочерние элементы текущего элемента-родителя. В OnInitNode заполняю поля структуры из текущей записи в MemTable  и перехожу к следующей. Достоинства -- экономное расходование памяти и высокая скорость, т.к. инициализируются только те элементы, которые простмотрел пользователь и для фильтрации используется метод SetRange/CancelRange по индексированным полям. Недостаток -- извращения с переключением Range у таблицы.

2 - "Полная инициализация":
 Рекурсивной строится полностью все дерево с помощью функции AddChild. В принципе на моих объемах данных тоже быстро и нет необходимости все время устанавливать/снимать Range, что в принципе проще. 


PM MAIL   Вверх
Bose
Дата 16.4.2007, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

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



uandriy, у меня используется древний наследник от VirtualTreeView(есть на офф. сайте delphigems в third-party examples), таким он мне достался от предшественника, а в исходники я не лазил. 

Если бы мне сейчас пришлось выбирать, я бы выбрал Dynamic DBTreeView control. 
В нём загрузка, насколько я понял из описания реализована более грамотно. 

Сейчас у меня работа с деревом происходит по второму методу. Т.е. Считываются все данные из базы, а после строится структура(насколько я понял принцип работы того компонента).

В Dynamic DBTreeView есть возможность выбрать способ. Реализовано это так: помимо полей OBJECT_ID, PARENT_ID там можно указать опциональное поле HAS_CHILDREN, которое будет использоваться для выяснения, есть ли у узла дети. Если поле HAS_CHILDREN присутствует, тогда инициализация детей и считывание данных происходит на лету, если не указано, то считываются все данные. Но, могу и ошибаться.
Кстати ещё один из плюсов этого компонента в том, что в нём для каждого столбца в дереве(Column) можно указать соответствующее поле из Datasetа.


Цитата(uandriy @  16.4.2007,  14:59 Найти цитируемый пост)
и для фильтрации используется метод SetRange/CancelRange по индексированным полям. Недостаток -- извращения с переключением Range у таблицы

это я вообще не понял. smile 

PM MAIL WWW Skype   Вверх
uandriy
Дата 16.4.2007, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 22.3.2007
Где: Украина, Днепропе ровск

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



Та ну, так не интересно. Сделал, чтобы все работало, но на Dynamic DBTreeView. Просто из-за того, что время поджимает оставлю пока что этот вариант, но все равно расковыряю с "ручной" обработкой в VirtualStringTree, т.к хочется разобраться что/почему/от чего и как....
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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