Форум: "Начинающим";
Текущий архив: 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;
OMGfor 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