在处理Lazarus中的项目之后,调整TListview中选定颜色的项目

问题描述 投票:0回答:1

花了很多时间之后

'''

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;

'''

我能够更改列表视图中项目的颜色。但是,我真正想要的是:

  1. 以黑色显示列表视图中的所有项目(完成,可以)
  2. 以编程方式遍历所有项目,然后一次选择1个项目(完成,可以),但是将字体颜色设置为红色(所选项目的颜色)。
  3. 读取项目的标题(文件名)并处理该文件名(完成,可以)
  4. 如果成功完成处理,则将当前项目设置为绿色,如果不成功,则将其保留为红色。
  5. 选择列表中的下一个项目,直到列表末尾(完成,确定)。

希望这很有道理。概括来说,这意味着:如何根据某个函数的结果更改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 tlistview
1个回答
0
投票

我没有安装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值进一步修改背景或字体颜色。

© www.soinside.com 2019 - 2024. All rights reserved.