Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» VirtualTreeView

Автор: B2D
Дата сообщения: 10.08.2006 12:53
Более менее с обычным деревом разобрался, теперь охота разобраться с "загодочным" VirtualTreeView. Все его хвалят и не могут нарадоваться на него. У меня возник вопрос- почему?
Одни говорят-строиться быстрее стнандартого, другие-визуально намного функционнальнее, третьи-"короче лучше".
Насчет того,что визуально функционнальнее согласен (видно даже моим невооруженным взгядом), но то, что быстрее-дудки, не смог увидеть на примере (дерево 20000 элементов).
Где почитать нормальных статей о преимуществах и способах использования ИМЕННО VirtualTreeView?
Может есть другие аналоги VirtualTreeView, которые могут составить конкуренцию ему?

Добавлено:
Да, мне деревья надо использовать при работе с БД
Автор: verhovetc
Дата сообщения: 10.08.2006 15:16

Цитата:
Где почитать нормальных статей о преимуществах и способах использования ИМЕННО VirtualTreeView?

для начала в помощи к этому компоненту и в демках с ним идущих

а вот быстрота зависит не только от компонента
Автор: unikum
Дата сообщения: 10.08.2006 16:24
я в свое время делал тесты и должен сказать что обычный TTreeView в режиме virtual соизмеримо работал с этим TVirtualTreeView, но из-за визуальных фенечек отдал предпочтение второму контролу. Хотя безусловно, его заставить нармально работать чуть дольше.
Примеры идут очень толковые, не ленись смотреть, там же и хелпина.
Автор: mrrex
Дата сообщения: 10.08.2006 21:38
B2D

Цитата:
Насчет того,что визуально функционнальнее согласен (видно даже моим невооруженным взгядом), но то, что быстрее-дудки, не смог увидеть на примере (дерево 20000 элементов).

можешь не сомневаться.

verhovetc

Цитата:
а вот быстрота зависит не только от компонента

абсолютая правда.
Если вставлять по 1 узлу, то выигрыш хоть и будет, но не сильный. а если в полной мере применять технологию вставки VT - мама не горюй стандартное дерево отдыхает.
Это как раз заметно на больших наборах данных.


Цитата:
Да, мне деревья надо использовать при работе с БД

да ради бога, я вот например вовсю VT юзаю. Типа свой универсальный каталогизатор делаю и довольно успешно. Кстати я этот компонент не только как дерево но и как обычный грид использую. Супер. больше мне ничего не надо.

Если вопросы будут - пиши, можно в мыло сразу.
rexir(страшный пес) nm ru (думаю понятно.)

Автор: Pinocchio
Дата сообщения: 11.08.2006 12:04
B2D

Цитата:
Одни говорят-строиться быстрее стнандартого

Из моего опыта со стандартным компонентом оказалось вполне очевидным отделять визуальный компонент от самого (программной сущности) дерева, так как фишка с заполнением естественно есть. Присваивание через LoadFromStream(TTreeStrings) всегда работало быстрее любых остальных методов. Т.е. готовится иерархический список строк с табуляциями, загружается, а уже потом заполняются картинки и т.д.
С VirtualTreeView надо разбираться именно ради визуальных эффектов. Думаю, что вопрос быстродействия решается так же - физика иерархии отдельно и визуальное поведение отдельно.
Автор: Pinocchio
Дата сообщения: 14.08.2006 10:34
mrrex
Интересно было бы узнать о новинках, т.к. компонент наблюдал очень давно. Сейчас скачал новый, - по крайней мере демка вызывает интерес (что касается постепенного построения дерева).
Автор: unikum
Дата сообщения: 15.08.2006 10:57
2Pinocchio

Цитата:
Из моего опыта со стандартным компонентом оказалось вполне очевидным отделять визуальный компонент от самого (программной сущности) дерева, так как фишка с заполнением естественно есть

А в какой тогда структуре ты хранишь древовидные данные?
Автор: LulumbaZ
Дата сообщения: 15.08.2006 11:09
Dynamic DBTreeView controls (нттп://www.table-report.com/products.php)

Dynamic DBTreeView controls are based on Virtual TreeView control. They are using clone dataset for internal data manipulation when dynamically building tree nodes and a binary search list for detecting existing nodes. They reflect all changes of underlining dataset (record insertion, deletion, field value change) and support drag and drop operation. There are three controls: TDTADOTree, TDTClientTree, TDTTableTree for TCustomADODataSet, TCustomClientDataSet and TTable accordingly. If your dataset supports filtering and you can create its clone dataset, you can derive your own treeview by overriding CreateCloneDataSet method of the TDTCustomDBTreeView control.

Freeware. Full source included. File size 896 KB.

Автор: anat75
Дата сообщения: 15.08.2006 14:04
mrrex
А можешь сюда запостить примерчики?
Тоже хотелось-бы использовать.....
Автор: Pinocchio
Дата сообщения: 15.08.2006 15:04
unikum
В пределах процесса в глобальном массиве, хотя такое требуется не часто.
Автор: unikum
Дата сообщения: 15.08.2006 17:42

Цитата:
В пределах процесса в глобальном массиве, хотя такое требуется не часто.

Ну дык массив то не дерево. Или у элементов хранишь инфо типа parent/childs для построения дерева?
Автор: Pinocchio
Дата сообщения: 16.08.2006 15:41

Цитата:
Ну дык массив то не дерево.

Если массив Tree назвал, cтало быть инфо для построения в массиве.
Автор: unikum
Дата сообщения: 16.08.2006 17:52
т.е. в масиве инфо как ноды в распахнутом дереве?
А как ты поступаешь в случае дабавления/удаления нодов, массив колбасишь?
Автор: mrrex
Дата сообщения: 16.08.2006 19:43
anat75
примерчики чего?
давайте просьбы в аську. 257892099 мане не жалко.
Автор: Pinocchio
Дата сообщения: 17.08.2006 15:22
С массивом - детали,

Цитата:
Думаю, что вопрос быстродействия решается...

Автор: akaGM
Дата сообщения: 22.08.2006 15:24
mrrex

Цитата:
Кстати я этот компонент ... и как обычный грид использую.


ячейки грида делал редактируемыми? вполне хватило бы чисел и строк...
можешь примером поделиться? а то поставляемый как-то не очень...
можно прям в мыло:
akagm на yandex.ru

--------
прошу пардону, аськи сейчас временно нет, комп -- казённый...
Автор: mrrex
Дата сообщения: 22.08.2006 20:10
akaGM

Цитата:
ячейки грида делал редактируемыми? вполне хватило бы чисел и строк...
можешь примером поделиться? а то поставляемый как-то не очень...


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

вот тут анату75 замылил ответ, чтоб втуне не пропадало повторяю здесь.
немного не в тему akaGM, сорри

> 1. Есть список имён с номерами для каждого. Например
> Иванов(1-25,1-36), Петров(6-36, 7-48), Сидоров (8-48,9-21).
не совсем понятно, но я предполагаю, что это номера служебных
телефонов. Это просто уточнение структуры
хранимой информации. т.е. каждый чел имеет два номера.
> Как организовать дерево? Что объявить? Что-куда "запихивать"?

для начала, создаем структуру, которая описывате хранимые данные.
количество и типы полей НЕ обязателно соответсвуют столбцам таблицы.
просто в большинстве случаев это (их соответсявие) гораздо ....
ээээ.... проще.
Итак.
в начале Cpp файла (апосля инклюдов и прагм) объявляем (применительно
к твоему примеру ):

Код:
typedef struct
{
Ansistring Name; //-- ФИО
Ansistring tel1, tel2; //-- телефоны
}TPeople;
Автор: akaGM
Дата сообщения: 22.08.2006 21:17
mrrex
ясн, спас...
т.к. я триВью вообще не знаю, мне всё равно на чём исходники...
лично я подожду до сентября...
Автор: mrrex
Дата сообщения: 22.08.2006 22:14
akaGM
млин, да мне ж потом стыдна будет!

Пример будет слегка изменен, относительно того, как я видел в авторском тексте.
Это реально работающий код для C++ Builder 5/6/2006

сперва создаем файл, который будет описывать 'внедряемый' объект редактирования

назовем его unt_PropEdit.h


Код:
#include "VirtualTrees.hpp"

#ifndef unt_PropEditH
#define unt_PropEditH
//---------------------------------------------------------------------------
//-- редактор свойств для дерева характеристик экземпляров
class TEditLink : public IVTEditLink {
ULONG FRefCount; // used by our own implementation of the interface
protected:
// private members
void __fastcall EditWindowProc (TMessage &Message);
void __fastcall EditKeyDown (TObject* Sender, WORD &Key, TShiftState Shift);
public:
TWinControl* FEdit; // regardless of the type of edit control we use
int FColumn; // we save our own info about,
TBaseVirtualTree* FTree; // parent, tree, node, column and our data
TVirtualNode* FNode;
TWndMethod FOldEditProc; // used to capture some important messages
TColor FColor; //-- цвет элемента управления
bool FStopping; // local merker
    // Constructor/Destructor
    __fastcall TEditLink(TBaseVirtualTree* Tree, TVirtualNode* Node, TColumnIndex Column,TColor Color=clWhite);
    //-- параметр TColor - моя художественная вольность
    // IUnknown members
    virtual ULONG __stdcall AddRef ();
    virtual ULONG __stdcall Release ();
    virtual HResult __stdcall QueryInterface (const GUID& IID, void** ppv);
    // IVTEditLink members
    virtual bool __stdcall BeginEdit (void);
    virtual bool __stdcall CancelEdit (void);
    virtual bool __stdcall EndEdit (void){return true;};
    virtual bool __stdcall PrepareEdit (TBaseVirtualTree* Tree, PVirtualNode Node, TColumnIndex Column) {return false;};
    virtual TRect __stdcall GetBounds (void);
    virtual void __stdcall SetBounds (const TRect R);
    virtual void __stdcall ProcessMessage (Messages::TMessage &Message);
};

#endif
Автор: akaGM
Дата сообщения: 22.08.2006 22:28
ок, демку запросил...

ты эта... код под псевдотегом "more" скрывай, а то обидятся ещё...

самый последний в:
http://i.ru-board.com/codes.html
Автор: mrrex
Дата сообщения: 25.08.2006 13:46
Ну, как и обещал продолжаю.
Да. Сразу хочу оговориться, примеры для Делфей есть в ДЕМО программе дерева.
Дельфистам лучшее смотреть именно туда.

Итак.

Базовый обьект редактора мы сделали.
теперь определяем его наследника, для каждого дерева - свой. Хотя можно и один для
нескольких, как душа просит.

Следующий код - в заголовочном файле окна, содержащего дерево.
Обращайте внимание на //-- выделенные комментарии
ну и на другие тоже
[more]

Код:
#include "unt_PropEdit.h"

//-- здесь определяется структура данных для узла в дереве
//-- данная структура используется для построения перечня отношений, существующих в каталоге
typedef struct
{
int relID; //-- ID отношения в БД
AnsiString relName; //-- название отношения
AnsiString relCode; //-- классификационный код отношения
bool relNasled; //-- признак наследования
int relClID; //-- идентификатор класса, к которому принадлежит отношение
//-- 0 - если отношение общее для всех классов
bool Processed;
}TRels;

//--наследник класса - встраиваемого редактора. Все лишнее удалено
//-- редактор свойств для перечня отношений
class TRelEdit : public TEditLink {
TRels* FData;
public:
    // Constructor/Destructor
    __fastcall TRelEdit(TVirtualStringTree* Tree, TVirtualNode* Node, TColumnIndex Column, TRels* Data);
    //-- последний параметр функции - структура данных
    virtual bool __stdcall EndEdit(void);
    virtual bool __stdcall PrepareEdit(TBaseVirtualTree* Tree, PVirtualNode Node, TColumnIndex Column);
};
Автор: Pinocchio
Дата сообщения: 25.08.2006 17:27
Ну а для дельфи паскал будет не лишним, чтобы начать.
[more]
...
type
TVirtStringTree = class;
TTreeNode = class(TObject)
private
FVirtualNode: PVirtualNode;
procedure SetText(const Value: string);
public
property Text: string read FText write SetText;
end;

TVirtualTreeNodes = class(TPersistent)
private
FTreeView: TVirtStringTree;
function GetNodeFromIndex(Index: Integer): TTreeNode;
public
property Item[Index: Integer]: TTreeNode read GetNodeFromIndex; default;
property TreeView: TVirtStringTree read FTreeView;
end;

TVirtStringTree = class(VirtualTrees.TVirtualStringTree)
private
FTreeNodes: TVirtualTreeNodes;
function GetNodeFromVirtual(Node: PVirtualNode): TTreeNode;
procedure SetNodeToVirtual(Node: PVirtualNode; const Value: TTreeNode);
protected
property TreeNode[Node: PVirtualNode]: TTreeNode read GetNodeFromVirtual
write SetNodeToVirtual;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;

...

implementation

...

type
PToNode = ^TToNode; TToNode = record ToNode: TTreeNode; end;

...

function TVirtStringTree.GetNodeFromVirtual(
Node: PVirtualNode): TTreeNode;
var
P: PToNode;
begin
P:=GetNodeData(Node);
if P <> nil then Result:=P.ToNode
else Result:=nil;
end;

procedure TVirtStringTree.SetNodeToVirtual(Node: PVirtualNode;
const Value: TTreeNode);
var
P: PToNode;
begin
P:=GetNodeData(Node);
if P <> nil then P.ToNode:=Value;
end;

...
[/more]
Автор: SALAR
Дата сообщения: 16.09.2009 13:59
Помогите, кто работал в Delphi с VT. Несколько дней уже бьюсь и не могу преодолеть следующий глюк. Заполняю в процедуре InitNode данные узлов:
with Sender do begin
Data:= GetNodeData(Node);
Initialize(Data^);
Data.AMaterialGroupNumber:=tblMaterialGroupData.FieldByName('Id_group').AsInteger;
Data.AMaterialGroupName:=tblMaterialGroupData.FieldByName('MaterialGroupName').AsString;
Data.Caption := Format('Level %d, Index %d', [GetNodeLevel(Node), Node.Index]);
end;
with query1 do
begin
close;
SQL.Clear;
SQL.Add('Select MaterialName from Material.db where id_group=:P_TABLE1_ID');
ParamByName('P_TABLE1_ID').AsInteger:=Data.AMaterialGroupNumber;
open;
end;
if Query1.RecordCount > 0 then
begin
Include(InitialStates, ivsHasChildren); Query1.First;
for i:=0 to Query1.RecordCount-1 do
begin
ChildNode:=Sender.AddChild(Node);
with Sender do
begin
ChildData:=GetNodeData(ChildNode);
Initialize(ChildData^);
ChildData.Caption:=Query1.Fields[0].AsString;
ChildData.AMaterialGroupNumber:=Data.AMaterialGroupNumber;
ChildData.AMaterialGroupName:=Data.AMaterialGroupName;
end;
Query1.Next;
end;
end;
if not tblMaterialGroupData.eof then
tblMaterialGroupData.Next;
Как видите, формирую корневые узлы и дочерние, где меняется только Caption.
Когда я в событии GetText пытаюсь отобразить подписи узлов:
Data := Sender.GetNodeData(Node);
case Sender.GetNodeLevel(Node) of
0:
if Assigned(Data) then
Text:=Data.AMaterialGroupName;
1: begin
Text:=Data.Caption;
end;
end;
то для дочернего узла отображается caption из данных корневого узла, как будто данные дочернего узла не инициализировались. В отладчике, в строке
Text:=Data.Caption;
параметр node почему то соответствует последнему корневому узлу (а он дочерних элементов не имеет), а не тому, с которого порождается дочерний элемент (level 1), поэтому и получается caption родительского узла.
Автор: AlexNMelnikov
Дата сообщения: 17.09.2009 23:43
Попробуйте вынести заполнение дерева в другое место, т.к. вроде здесь происходит вызов InitNode для каждого дочернего узла добавленного внутри InitNode.

Автор: G787
Дата сообщения: 18.09.2009 03:35
вот тут неплохой мануал по VTV на русском
Автор: SALAR
Дата сообщения: 23.09.2009 21:37
Спасибо ответившим. Действительно, отказался от работы с событием InitNode, заполняю форму в процедуре FormCreate. Тогда все получается.
Автор: G787
Дата сообщения: 23.01.2012 16:05
Народ кто успел скачать статью по ссылке из моего предыдущего поста ?
http://forum.vingrad.ru/forum/topic-97620.html
Автор: druff
Дата сообщения: 26.01.2012 13:18
А что с ней случилось?
Автор: svi73
Дата сообщения: 25.03.2012 21:14
А к XE2 кто нибудь прикрутить данный компонент сумел?
Автор: data man
Дата сообщения: 25.03.2012 21:21
svi73
А в чём проблема с "прикручиванием"?
Судя по логам есть поддержка и 64 бит.

Страницы: 12

Предыдущая тема: Сервер удаленного доступа


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.