Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.09.11;
Скачать: [xml.tar.bz2];

Вниз

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;



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

Форум: "Начинающим";
Текущий архив: 2011.09.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.004 c
2-1306413330
Очень злой
2011-05-26 16:35
2011.09.11
Inherited


2-1306129367
vasja123
2011-05-23 09:42
2011.09.11
ошибка при инициализации MCI


2-1306665558
Kamelot
2011-05-29 14:39
2011.09.11
Как нарисовать картинку, имея массив цветов пикселей?


15-1305992422
Leon-Z
2011-05-21 19:40
2011.09.11
Office 2003 против Office 2007


1-1266010470
LightGreen
2010-02-13 00:34
2011.09.11
Дублирование переменных в юнитах





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский