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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Заполнение VirtualTreeview class'ами, Как отобрзить в VirtualTree поля class' 
:(
    Опции темы
san46
Дата 15.6.2008, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Недавно установил VirtualTreeView.
В многочисленных примерах данные каждой ветки дерева хранятся в record'ах и оттуда через событийные механизмы отображаются в VirtualTreeView.
У меня же данные хранятся в классе, а экземпляры класса в TList. Никак не могу разобраться как заставить VirtualTreeView отображать данные не из рекорда, а из классов.
Может кто уже сталкивался с этим. Подскажите, пожалуйста.
PM MAIL   Вверх
Rennigth
Дата 15.6.2008, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

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



san46, А в чем проблема-то? Преобразовать поинтер в TObject(или что у тебя там)? NodeDataSize только 4 байта ставь.


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
san46
Дата 15.6.2008, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Да, ставил 4 байта. Примерно так:
Код

// делаю в FormeCreate
  VST.NodeDataSize := SizeOf(TData); 
//или  VST.NodeDataSize := 4;

Ошибка (run-time) в:
Код

procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var D : TData; //этот самый класс
begin
  D := Sender.GetNodeData(Node); //"D" после присвоения "Inaccessible value"
  if D <> nil then  //дальше, понятно, бардак
    CellText := D.Name;
end;

Т.е. нет ясного представления что делать, чтобы отображались значения полей класса.
PM MAIL   Вверх
Rennigth
Дата 15.6.2008, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

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



san46, 
а TData это что?

Добавлено @ 20:06
Код

procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var 
  P: Pointer;
begin
  P := Sender.GetNodeData(Node); //"D" после присвоения "Inaccessible value"
  if P <> nil then  //дальше, понятно, бардак
    CellText := TData(P).Name;
end;


Это сообщение отредактировал(а) Rennigth - 15.6.2008, 20:06


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
MetalFan
Дата 15.6.2008, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



Код

Sender.GetNodeData(Node)^



--------------------
There are always someone smarter than you...
PM MAIL   Вверх
san46
Дата 15.6.2008, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



san46, а TData это что?
TData - это класс (упрощенно): 
Код

TData = class 
  Name : string;
end;


Добавлено @ 20:06
Код

procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var 
  P: Pointer;
begin
  P := Sender.GetNodeData(Node); //"D" после присвоения "Inaccessible value"
  if P <> nil then  //дальше, понятно, бардак
    CellText := TData(P).Name;
end;

Таким образом уже делал, в run-time ошибка на последней строке "Access violation...". Впрочем, все равно какого типа лок. переменная Pointer или класс Tdata, все равно ошибка.

А присвоение P := Sender.GetNodeData(Node)^; компилятор не пропускает - "Incompatible type: ..."

Это сообщение отредактировал(а) san46 - 15.6.2008, 20:52
PM MAIL   Вверх
MetalFan
Дата 15.6.2008, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



Цитата(san46 @  15.6.2008,  20:41 Найти цитируемый пост)
А присвоение P := Sender.GetNodeData(Node)^; компилятор не пропускает - "Incompatible type: ..."

а головой подумать?
естественно надо "прикастовать" к своему классу

Добавлено через 1 минуту и 13 секунд
Код

procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var 
  P: Pointer;
begin
  P := Sender.GetNodeData(Node);
  if P <> nil then
    CellText := TData(P^).Name;
end



--------------------
There are always someone smarter than you...
PM MAIL   Вверх
san46
Дата 16.6.2008, 07:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Да, в голове одни опилки. Благодарю MetalFan, все, казалось, выкрутасы с указателями переделал, а P^ упустил.
Код

//вместо 
  CellText := TData(P).Name;
//надо
  CellText := TData(P^).Name;
 
Теперь VirtualTree смирно отображает все что надо.
PM MAIL   Вверх
MetalFan
Дата 16.6.2008, 07:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



san46, 
Норм, сам на этом однажды попался)  smile 



--------------------
There are always someone smarter than you...
PM MAIL   Вверх
pethead
Дата 3.10.2008, 10:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



тогда еще вопрос к топикстартеру: как собственно происходит заполнение? потом VT динамически отображает состояние объектов из списка TList? если в Tlist добавлен объект или удален? как это скажется на VT: что надо предпринять чтобы отображение удаленного объекта из VT удалилось, а новго отобразилось?

вот я что то написал... 
отображаются поля классов нормально. в три колонки. далее если я начинаю как то работать со списком объектов, удалять, добавлять, изменять их поля, то как в VT это все динамично отобразить?

Код

  TObj = class
   a,b,c:String;
  end;

  rTreeData = record
    Obj: TObj;
  end;


var
  Form1: TForm1;
  myList:TList;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
 i:Integer;
 tmpObj:TObj;
 NewNode: PVirtualNode;
 NodeD: ^rTreeData;

begin
 myList:=TList.Create;

 VT.NodeDataSize:=SizeOf(rTreeData);


for i:=0 to 100 do begin
  tmpObj:=TObj.Create;

  tmpObj.a:=IntToStr(Random(1000));
  tmpObj.b:=IntToStr(Random(1000));
  tmpObj.c:=IntToStr(Random(1000));

  myList.Add(tmpObj);

  NewNode:=VT.AddChild(nil);
  NodeD:=VT.GetNodeData(NewNode);
  NodeD.Obj:=tmpObj;

 end;

end;

procedure TForm1.VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
  P: Pointer;
begin
  P := Sender.GetNodeData(Node);
 if P <> nil then begin
   case Column of
    0: CellText := TObj(P^).a;
    1: CellText := TObj(P^).b;
    2: CellText := TObj(P^).c;
   end;
  end;
end;


например по кнопке я удаляю 5ый элемент в списке.
далее делаю так:
но что то мне тут не нравится... если объектов 10000? то будет задержка при очисте и заполнении на экране?

Код

procedure TForm1.Button1Click(Sender: TObject);
var
 i:Integer;
 NewNode: PVirtualNode;
 NodeD: ^rTreeData;
begin
 myList.Delete(5);

 VT.Clear;

 for i:=0 to myList.Count-1 do begin
  NewNode:=VT.AddChild(nil);
  NodeD:=VT.GetNodeData(NewNode);
  NodeD.Obj:=myList[i];
 end;

end;



Это сообщение отредактировал(а) pethead - 3.10.2008, 13:05
PM MAIL WWW ICQ   Вверх
pethead
Дата 3.10.2008, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



а все. сделал. без очистки всего МЕ при удалении. просто ввел новое поле в объекте где хранится укзатель на PVirtualNode.

и при удалении объекта, сперва удаляю Node по указателю в объекте, а потом сам объект. потом Refresh и все.

smile

Код

  TObj = class
   Node: PVirtualNode;
   a,b,c,d,e,f,g,h:String;
  end;

...
  при создании

  NodeD.Obj:=tmpObj;
  NodeD.Obj.Node:=NewNode;
...
 при удалении
 VT.DeleteNode(TObj(myList[i]).Node);
 TObj(myList[i]).Free;
 myList.Delete(i);

 VT.Refresh;





PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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