Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.09.11;
Скачать: CL | DM;

Вниз

TreeView Цветные строки   Найти похожие ветки 

 
kirat ©   (2011-05-25 12:29) [0]

Подскажите пожалуйста как сделать цветные строки при их создании?
....
public
   izm:integer;
 end;
.....

procedure TForm1.Button1Click(Sender: TObject);
var
node:TTreeNode;
begin
izm:=1;
node:=TreeView1.Items.AddChild(nil,"sdf");
izm:=0;
node:=TreeView1.Items.AddChild(nil,"sdsdfsdf");
izm:=1;
node:=TreeView1.Items.AddChild(node,"sdfsdfs");
izm:=0;
node:=TreeView1.Items.AddChild(nil,"sdfsdf,");
izm:=0;
node:=TreeView1.Items.AddChild(node,"sdf");
izm:=0;
node:=TreeView1.Items.AddChild(node,"sdf");

end;

procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
 Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if izm =1 then Sender.Canvas.Font.Color:= clRed;
end;


 
kirat ©   (2011-05-25 12:32) [1]

Вот так не получается!


 
Ega23 ©   (2011-05-25 12:47) [2]

izm:=1;
node:=TreeView1.Items.AddChild(nil,"sdf");
izm:=0;
node:=TreeView1.Items.AddChild(nil,"sdsdfsdf");
izm:=1;
node:=TreeView1.Items.AddChild(node,"sdfsdfs");
izm:=0;
node:=TreeView1.Items.AddChild(nil,"sdfsdf,");
izm:=0;
node:=TreeView1.Items.AddChild(node,"sdf");
izm:=0;
node:=TreeView1.Items.AddChild(node,"sdf");


Повеселил, спасибо!  :)


 
kirat ©   (2011-05-25 12:52) [3]

Ну вообще то оно по другому =) Но єто так на быструю руку! И как мне в зависимости от значения izm изменить цвет строки?


 
Ega23 ©   (2011-05-25 13:20) [4]

Дело в том, что метод TForm1.TreeView1CustomDrawItem вызывается по событию, в момент отрисовки TreeViewItem.
Какое значение в этот момент имеет твоя переменная izm - Аллах ведает.
Соответственно, если ты хочешь каким-бы то ни было способом отличать узлы в момент отрисовки, то тогда тебе нужно сохранить данную штуку в узел.
Для этого можно использовать TTreeNode.Data:


node:=TreeView1.Items.AddChild(nil,"sdf");
Node.Data := Pointer(1);
node:=TreeView1.Items.AddChild(nil,"sdsdfsdf");
Node.Data := Pointer(0);
node:=TreeView1.Items.AddChild(node,"sdfsdfs");
Node.Data := Pointer(1);
node:=TreeView1.Items.AddChild(nil,"sdfsdf,");
Node.Data := Pointer(0);
node:=TreeView1.Items.AddChild(node,"sdf");
Node.Data := Pointer(0);
node:=TreeView1.Items.AddChild(node,"sdf");
Node.Data := Pointer(0);


Соответственно, в момент вызова обработчика события:

procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if Integer(Node.Data)=1 then
 Sender.Canvas.Font.Color:= clRed;
end;


 
Dennis I. Komarov ©   (2011-05-25 13:38) [5]

Все, теперь стэк оверфлоу... :)


 
Ega23 ©   (2011-05-25 13:44) [6]


> Все, теперь стэк оверфлоу... :)


Почему?


 
Dennis I. Komarov ©   (2011-05-25 13:49) [7]


> Ega23 ©   (25.05.11 13:44) [6]

Ты меня не так понял, это не в IDE...


 
Kirat ©   (2011-05-25 13:49) [8]

Грамадное спасибо =)! Почему я сам к єтому не пришел =(?


 
Dennis I. Komarov ©   (2011-05-25 13:52) [9]

Только вряд ли твой Pointer(0) будет понят...
Да и бросал бы уж туда весь TColor, к чему извращения if?


 
Kirat ©   (2011-05-25 14:05) [10]

Мне надо пометить другим цветом те строки,  которые как бы помеченые на удаление. Если есть другой вариант то я не против посмотреть.


 
Dennis I. Komarov ©   (2011-05-25 15:20) [11]


> Если есть другой вариант то я не против посмотреть.

За чем другой? Просто я думаю, что он Вам не понятен (судя по [0]). Если это не так, то можно только порадоваться за Вас...


 
VirEx ©   (2011-05-25 17:31) [12]

// делаем объект с нужными свойствами
type
 TMyItem=class
 public
   isDelete:Boolean;
   //можно добавить дополнительные свойства
end;
-----

// добавляем в дерево объекты
var
 itm:TMyItem;
begin
node:=TreeView1.Items.AddChild(nil,"text1");
itm:=TMyItem.Create();
node.Data := Pointer(itm);

node:=TreeView1.Items.AddChild(nil,"text2");
itm:=TMyItem.Create();
node.Data := Pointer(itm);
----

//при щелчке на элементе делаем его удаляемым или наоборот
TreeView1.OnItemClick(Sender: TObject; Button: TMouseButton;    Node: TTreeNode; const Pt: TPoint)
begin
TMyItem(Node.Data).isDelete = not TMyItem(Node.Data).isDelete;
----

//в прорисовке каждого элемента
procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if TMyItem(Node.Data).isDelete then Sender.Canvas.Font.Color:= clRed
else
Sender.Canvas.Font.Color:= clBlack;
end;

//где-то в коде при нажатии кнопки удаляем все элементы помеченные на удаление в цикле
//притом цикл должен быть не for а while!
begin
i:=0;
while i<TreeView1.items.Count-1 do begin

if TMyItem(TreeView1.items[i].Data).isDelete then // удаляем этот элемент

i:=i+1;
end;


 
Dennis I. Komarov ©   (2011-05-25 18:01) [13]

Кто сказал, что черный по дефолту?


 
VirEx ©   (2011-05-25 18:05) [14]

да не помню какой, я дельфи уж год почти не запускал


 
Dennis I. Komarov ©   (2011-05-25 18:08) [15]

а не надо...
procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);


 
Ega23 ©   (2011-05-25 20:29) [16]

itm:=TMyItem.Create();
node.Data := Pointer(itm);

Зачем к указателю указатель приводишь?

begin
i:=0;
while i<TreeView1.items.Count-1 do begin
if TMyItem(TreeView1.items[i].Data).isDelete then // удаляем этот элемент
i:=i+1;
end;


OMG

for i := TreeView1.items.Count - 1 downto 0 do
begin
 И хоть сами узлы удаляй. Только для этого нефигово Items.BeginUpdate перед циклом сделать, цикл в try..finally обернуть, в finally - Items.EndUpdate;
end;


 
VirEx ©   (2011-05-25 21:13) [17]

>Ega23 ©   (25.05.11 20:29) [16]

спасибо кэп :)
утратил навыки


 
Kirat ©   (2011-05-26 10:55) [18]

Спасибо большое! А вот вопрос а как мне всю ветку поменять? на первом я то помечу что он Delete, а в остальных ветках тоже надо так сделать! Ато пока только прорисовка получается! (Данные попадают из БД)


 
MsGuns ©   (2011-05-26 13:02) [19]

>VirEx ©   (25.05.11 17:31) [12]

Хороший код, классы там всякие.. Еще оракл до кучи и цены не будет решению :)


 
Dennis I. Komarov ©   (2011-05-26 13:21) [20]


> Kirat ©   (26.05.11 10:55) [18]

Дык сперва надо БД редактировать, а уж только потом ГУИ дергать...


 
KSergey ©   (2011-05-26 14:14) [21]

> MsGuns ©   (26.05.11 13:02) [19]
> >VirEx ©   (25.05.11 17:31) [12]

Их еще удалять надо при удалении ноды дерева...


 
Kirat ©   (2011-05-26 14:23) [22]

Так в БД редактируется. Только там громадное количество данных и прорисовка снова занимает много времени. Это конечно не глобально, но хотелось бы чтобы быстрее. А на данный момент я удаляю все дерево и заново его делаю =(!!!


 
Ega23 ©   (2011-05-26 14:25) [23]


> Их еще удалять надо при удалении ноды дерева...


Нет проблем.

type

 TMyTreeNode = class (TTreeNode)
 public
    destructor Destroy; override;
 end;

destructor TMyTreeNode.Destroy;
begin
 if (Data <> nil) then
   TObject(Data).Free;
end;

procedure TForm1.TreeView1CreateNodeClass(Sender: TCustomTreeView;
 var NodeClass: TTreeNodeClass);
begin
 NodeClass := TMyTreeNode;
end;


Ну и следить внимательно, чтобы в data действительно объект сидел.


 
Ega23 ©   (2011-05-26 14:27) [24]


> Только там громадное количество данных и прорисовка снова
> занимает много времени.


TreeView.Items.BeginUpdate;
try
 // Работа с узлами
finally
 TreeView.Items.EndUpdate;
end;


 
VirEx ©   (2011-05-26 14:32) [25]

>KSergey ©   (26.05.11 14:14) [21]

так он я так понимаю в дереве при нажатии на ноде помечает на удаление (шрифт нода краснеет), а затем отдельной кнопкой удаляет помеченые, что и приведено в моем коде

однако в цикле удаления желательна проверка: если из базы удалена запись привязаная к ноду, тогда ноду нужно удалить


 
Dennis I. Komarov ©   (2011-05-26 15:19) [26]


> однако в цикле удаления желательна проверка: если из базы
> удалена запись привязаная к ноду, тогда ноду нужно удалить

Той записи уже может и не быть вовсе, а нод при этом еще оприсован...


 
VirEx ©   (2011-05-26 15:25) [27]

>Dennis I. Komarov ©   (26.05.11 15:19) [26]
>
> > однако в цикле удаления желательна проверка: если из базы
> > удалена запись привязаная к ноду, тогда ноду нужно удалить
>
> Той записи уже может и не быть вовсе, а нод при этом еще оприсован...


о_О каким образом если удаляет он только через дерево?


 
Dennis I. Komarov ©   (2011-05-26 15:31) [28]

Да мало ли желающих...


 
Kirat ©   (2011-05-26 16:20) [29]

Но перед єтим надо всей ветке передать isDelete=true


 
Dennis I. Komarov ©   (2011-05-26 16:30) [30]


> Kirat ©   (26.05.11 16:20) [29]

Ага, и потом рекурсией на равне с нодами удаляешь по одной записи на нод...
проект в помойку...


 
Kirat ©   (2011-05-26 16:58) [31]

Понял! Лучше перерисовать.


 
VirEx ©   (2011-05-26 17:20) [32]

>Dennis I. Komarov ©   (26.05.11 15:31) [28]

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


 
VirEx ©   (2011-05-26 17:22) [33]

>Kirat ©   (26.05.11 16:20) [29]

o_O


 
Ega23 ©   (2011-05-26 17:22) [34]


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


Нажал "Обновить" - обновилось.
Нажал "Удалить" - выполнилось Delete from table where id=
Ну а если уже удалено - ничего страшного.


 
Dennis I. Komarov ©   (2011-05-26 17:38) [35]


> Kirat ©   (26.05.11 16:58) [31]
> Понял! Лучше перерисовать.

Конечно да, эдак так штук 10000 нодов :) Юзеры расстреляют...


 
Amoeba_   (2011-05-26 17:46) [36]


> Юзеры расстреляют...

Не успеют. От икоты сам помрет.


 
Kirat ©   (2011-05-26 18:26) [37]

при 1000 значений пол секунды примерно. Что максимуму (теореотически) может быть 300. Правда хотелось бы быстрее


 
Ega23 ©   (2011-05-26 20:04) [38]


> Конечно да, эдак так штук 10000 нодов :) Юзеры расстреляют.


Я как-то давно TDBTreeView писал. Дерево на ~ 2000 узлов строилось около полутора секунд (включая время отработки ХП на удалённом сервере БД)


 
virex(work)   (2011-05-27 06:34) [39]


// делаем объект с нужными свойствами
type
TMyItem=class
public
  isDelete:Boolean;
  id:String;
end;
-----

//добавляем в дерево объекты
var
itm:TMyItem;
i:Integer;
title:String;
cursor:TCursor;
begin
//делаем выборку нужных записей из базы
cursor=db.rawQuery("Select title,id from table;");
cursor.moveToFirst(); //перемещаемся на первую запись
for i:=0 to cursor.getCount-1  do begin
//здесь в цикле желательно проверять, существует ли запись которую мы хотим извлечь из базы
//возможно она уже удалена из другого экземпляра программы, другим юзером

title:=cursor.getString(0);
node:=TreeView1.Items.AddChild(nil,title);
itm:=TMyItem.Create();
itm.isDelete:=false; //не удалять
itm.id:=cursor.getString(1);//берем из базы значение ключевого поля по которому будем удалять
node.Data := itm;
cursor.moveToNext(); //следующая запись
end;//for
end;
-----

//процедура удаления помеченных нодов
var
i:integer;
itm:TMyItem;
begin
for i := TreeView1.items.Count - 1 downto 0 do begin
itm:=TMyItem(TreeView1.items[i].Data);
if not Assigned(itm) then continue;//если объекта нет - пропускаем... break или continue? точно не помню как пропустить выполнение текущей итерации в цикле

//помечен на удаление?
if itm.isDelete then
 //удаляем запись в таблице
 if db.ExecSQL(format("Delete from table where id="%s";",itm.id)) then begin
  //вобще лучше удалять в отдельном потоке, но для простоты, чтобы не "замерзало" окно
  Application.ProcessMessages;
  //для плавной перересовки дерева
  TreeView.Items.BeginUpdate;
  try
  //тут удаляем ноду
  TreeView.Items.Delete(i); //вроде так удаляется?
  //точно не помню, вроде объект нужно вручную удалять, если так, тогда
   try
    itm.Free;
   finally
   end;
  finally
   TreeView.Items.EndUpdate;
  end;//try
 end;//if db.ExecSQL
end;//for
end;


p/s/ объекты db:TDataBase и cursor:TCursor абстрактные классы, для примера (db.ExecSQL, db.rawQuery, cursor.moveToFirst(), cursor.moveToNext(), cursor.getString(0) - это из java для android :) )


 
virex(work)   (2011-05-27 06:41) [40]

и еще, в процедуре удаления помеченных нодов
if not Assigned(itm) then continue;
лучше удалить ноду, т.к. она в любом случае "не рабочая" без объекта TMyItem

if not Assigned(itm) then begin
 Application.ProcessMessages;
 TreeView.Items.BeginUpdate;
 try
   TreeView.Items.Delete(i);
 finally
   TreeView.Items.EndUpdate;
 end;//try
 continue;
end;


 
Dennis I. Komarov ©   (2011-05-27 09:38) [41]


> Ega23 ©   (26.05.11 20:04) [38]
> > Конечно да, эдак так штук 10000 нодов :) Юзеры расстреляют.
> Я как-то давно TDBTreeView писал. Дерево на ~ 2000 узлов
> строилось около полутора секунд (включая время отработки
> ХП на удалённом сервере БД)

Олег, ну ты же при этом не отрисовывал все ноды :)


 
Ega23 ©   (2011-05-27 10:36) [42]


> Олег, ну ты же при этом не отрисовывал все ноды :)


Ну не FullExpand, конечно, но что-то отрисовывалось.


 
Kirat ©   (2011-05-27 11:56) [43]

Не могу понять "db.rawQuery("Select title,id from table;");" Вот єто что?


 
VirEx ©   (2011-05-27 12:06) [44]

>Kirat ©   (27.05.11 11:56) [43]
> Не могу понять "db.rawQuery("Select title,id from table;");" Вот єто что?


это выбор двух полей: заголовок title и уникальный идентификатор id


 
kirat ©   (2011-05-27 14:14) [45]

Ну я SQL знаю, и довольно не плохо! Но не могу понять db.rawQuery.
Я выборку делаю так:
QueryGroup.Close;
QueryGroup.SQL.Clear;
QueryGroup.SQL.Add("SELECT NAME, ID_ARTICLES_GROUP, PARENT_ID_ARTICLES_GROUP, DEL FROM GROUP");
QueryGroup.Open;


 
VirEx ©   (2011-05-27 14:20) [46]

>kirat ©   (27.05.11 14:14) [45]

см. [39], это абстракция, в дельфи этого нет, просто для наглядности взял из проекта для андроида java классы и методы
переделайте для себя


 
Kirat ©   (2011-05-27 14:28) [47]

Тьфу. А я то думаю, то ли лыжи не едут то ли...
Спасибо!



Страницы: 1 2 вся ветка

Текущий архив: 2011.09.11;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.009 c
2-1306344649
xozain
2011-05-25 21:30
2011.09.11
Работа с ТХТ


3-1263670520
dest81
2010-01-16 22:35
2011.09.11
Firebird set <параметр>= значение


2-1306057843
Criptonik
2011-05-22 13:50
2011.09.11
Вывод системных файлов


15-1304879894
Lutdan
2011-05-08 22:38
2011.09.11
Кто может помочь дописать программу БД? (возможно за $)


15-1305564549
Leon-Z
2011-05-16 20:49
2011.09.11
Delphi 2005 и Delphi 7.