花了很多时间之后
'''
procedure Tf100.lvListCustomDrawItem(Sender: TCustomListView; Item: TListItem;
State: TCustomDrawState; var DefaultDraw: Boolean);
begin
Sender.Canvas.Font.Color := clRed; // default was clBlack
end;
procedure Tf100.lvListCustomDrawSubItem(Sender: TCustomListView;
Item: TListItem; SubItem: Integer; State: TCustomDrawState;
var DefaultDraw: Boolean);
begin
Sender.Canvas.Font.Color := clRed; // Default was clBlack;
end;
'''
我能够更改列表视图中项目的颜色。但是,我真正想要的是:
希望这很有道理。概括来说,这意味着:如何根据某个函数的结果更改TListItem的颜色。我什至不知道在什么情况下应该调用此函数(在listview的情况下?)。
现在,我有这个:
iIndex := 0;
repeat
pbProgress.Position := iIndex + 1;
try
lvList.SetFocus; // The color should become clRED
lvList.ItemIndex := iIndex;
lvList.Items[iIndex].Selected := true;
lvList.Selected.MakeVisible(True);
sFile := txtFolder.text + '\' + lvList.Items[iIndex].Caption;
DisplayPicture(sFile);
application.processmessages ;
txtCurrent.Text := Format('%D of %D',[iIndex + 1, iMax]);
bOke := ProcessFile(sFile);
if (bOke) then begin
// Current index color should become clGREEN but I don't know how
end;
except
on E:Exception do begin
bOke := False;
msgbox(Format('Error at index %d',[iIndex]),'ooops',acError,[mbOk],['Press']);
end;
end;
if (bOke) then
Inc(FGood)
else
Inc(FWrong);
UpdateStats(Self);
Inc(iIndex);
until (iIndex = iMax);
希望有人能够回答我的问题。最好的祝福,马丁
我没有安装Lazarus,因此使用Delphi完成以下操作。我确定99.9%的产品也对您有用。
您已经了解了如何在OnCustomDrawItem()
和OnCustomDrawSubItem()
事件中定义项目的颜色。
这里重要的是要了解TListView
不会在任何地方保存该颜色设置。如果考虑上下滚动列表,则列表视图会根据需要绘制每个项目的OnCustomDrawItem()
和OnCustomDrawSubItem()
事件。自先前显示以来,项目的状态可能已更改。
因此,您需要将文件处理的结果保存在某个位置,以便可以在OnCustomDrawItem()
和OnCustomDrawSubItem()
事件中告诉列表视图每个项目使用什么颜色。
我建议您创建一个数据结构,一个简单的类,其中包含文件名和处理结果。然后,将文件添加到列表视图进行显示时,还将对每个文件对象的引用添加到列表视图。
首先是一些类型和变量声明
type
// enum for the different processing states
TProcessEnum = (NotDone, Processing, DoneSucceeded, DoneFailed);
// class for holding file names and process state
TMyFileData = class
FileName: string;
ProcessState: TProcessEnum;
end;
// Array type for file data
TMyFileDataArray = array of TMyFileData;
const
// string representation for process states
ProcessStates: array of string = ['Not done', 'Processing', 'Succeeded', 'Failed'];
var
// data array
MyFileDataArray: TMyFileDataArray;
然后创建一些演示数据
procedure TForm21.FormCreate(Sender: TObject);
var
i: integer;
begin
SetLength(MyFileDataArray, 9);
for i := 0 to Length(MyFileDataArray)-1 do
begin
MyFileDataArray[i] := TMyFileData.Create;
MyFileDataArray[i].FileName := 'c:\tmp\example'+IntToStr(i)+'.txt';
MyFileDataArray[i].ProcessState := NotDone;
end;
end;
然后将文件名和数据引用添加到LV项目,并将过程状态添加到LV子项目。数据引用是AddItem()
的第二个参数,以后可以使用OnCustomDrawItem()
OnCustomDrawSubItem()
和Item.Data
事件中进行访问。procedure TForm21.Button1Click(Sender: TObject);
var
i: integer;
begin
for i := 0 to Length(MyFileDataArray)-1 do
begin
ListView1.AddItem(MyFileDataArray[i].FileName, MyFileDataArray[i]);
ListView1.Items[i].SubItems.Add(ProcessStates[ord(MyFileDataArray[i].ProcessState)]);
end;
end;
并运行所有文件的处理
procedure TForm21.Button2Click(Sender: TObject);
var
i: integer;
begin
for i := 0 to Length(MyFileDataArray)-1 do
begin
MyFileDataArray[i].ProcessState := processing;
ListView1.Items[i].SubItems[0] := ProcessStates[ord(MyFileDataArray[i].ProcessState)];
ListView1.Repaint; // force a visual update
sleep(500); // simulate processing delay
MyFileDataArray[i].ProcessState := TProcessEnum(random(2) + 2);
ListView1.Items[i].SubItems[0] := ProcessStates[ord(MyFileDataArray[i].ProcessState)];
ListView1.Repaint; // force a visual update
end;
end;
帮助程序功能将ProcessState转换为颜色
function TForm21.ItemColor(ProcessState: TProcessEnum): TColor;
begin
case ProcessState of
DoneSucceeded: Result := clGreen;
Processing,
DoneFailed: Result := clRed;
else
Result := clBlack;
end;
end;
OnCustomDrawItem()
和OnCustomDrawSubItem()
都只有下面一行
Sender.Canvas.Font.Color := ItemColor(TMyFileData(Item.Data).ProcessState);
不过请注意,您可能想根据State: TCustomDrawState
值进一步修改背景或字体颜色。