Delphi 颜色列表框。项[N],其中N由代码生成

Delphi 颜色列表框。项[N],其中N由代码生成,delphi,Delphi,我有一个列表框。我使用以下方法将其填充为一个文件: IF Opendialog1.Execute then BEGIN Listbox1.Items.LoadfromFile(OpenDialog1.FileName); END; 加载的文件包含数字,并且仅包含数字(我假定)。 当然,我现在开始扫描:(伪代码:) 对于N:=0直到Listbox1.Items.Count-1 DO 开始 NUM:=ScanForNotNumberInListbox1Item(Listbo

我有一个列表框。我使用以下方法将其填充为一个文件:

IF Opendialog1.Execute then
   BEGIN
      Listbox1.Items.LoadfromFile(OpenDialog1.FileName);
   END;
加载的文件包含数字,并且仅包含数字(我假定)。 当然,我现在开始扫描:(伪代码:)

对于N:=0直到Listbox1.Items.Count-1 DO
开始
NUM:=ScanForNotNumberInListbox1Item(Listbox1.Items[N]);
// 
//如果满足非数字,则返回NUM=-1。。
//    
如果NUM为0,则
开始
LISTBOX1.Items[N]。背景颜色:=红色;
出口(*或终止*)
结束;
结束;
我知道我必须使用LIstbox1.DrawItem();我们已经尝试了几个在Stack Exchange中显示的示例,但是使用的示例似乎都不是代码生成的

那我该怎么做呢


Kris

为列表框设置
lbOwnerDrawFixed
(或另一个ownerdraw)样式

列表框项具有辅助属性
Objects[]
,您可以将无效项的
Objects[i]
设置为非零值

IF NUM <> 0 then      
    LISTBOX1.Objects[N] := TObject(1);
如果NUM为0,则
LISTBOX1.Objects[N]:=TObject(1);
在绘图过程中,使用
OnDrawItem
事件处理的一些示例,并使用
对象[]
定义背景色 您可以将关于每个列表项的附加信息存储在其关联的“对象”中。这可以是一个(指向一个)真实对象的指针,也可以使用这个指针大小的整数来编码任何需要的简单信息

作为一个简单的示例,让我们将项目的背景颜色放在该字段中(
使用数学)
):

不要忘记将列表框的
Style
属性设置为
lbOwnerDrawFixed
(比如)

更“高级”的方法是将实际对象与每个项目关联:

type
  TItemFormat = class
    BackgroundColor: TColor;
    TextColor: TColor;
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  ItemFormat: TItemFormat;
begin

  ListBox1.Items.BeginUpdate;
  try
    ListBox1.Clear;
    for i := 1 to 100 do
    begin
      ItemFormat := TItemFormat.Create;
      ItemFormat.BackgroundColor := IfThen(Odd(i), clSkyBlue, clMoneyGreen);
      ItemFormat.TextColor := IfThen(Odd(i), clNavy, clGreen);
      ListBox1.Items.AddObject(i.ToString, ItemFormat);
    end;
  finally
    ListBox1.Items.EndUpdate;
  end;

end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
var
  ListBox: TListBox;
  Canvas: TCanvas;
  ItemFormat: TItemFormat;
  S: string;
begin
  ListBox := Control as TListBox;
  Canvas := ListBox.Canvas;
  ItemFormat := ListBox.Items.Objects[Index] as TItemFormat;

  Canvas.Brush.Color := ItemFormat.BackgroundColor;
  Canvas.FillRect(Rect);
  S := ListBox.Items[Index];
  Canvas.Font.Color := ItemFormat.TextColor;
  Canvas.TextRect(Rect, S, [tfSingleLine, tfVerticalCenter]);
end;

(在本例中,您拥有这些对象,因此您有责任在不再需要它们时释放它们。)

将一切付诸行动 在你的特殊情况下,我想试试

procedure TForm1.Button1Click(Sender: TObject);
var
  i, dummy, FirstInvalidIndex: Integer;
begin

  with TOpenDialog.Create(Self) do
    try
      Filter := 'Text files (*.txt)|*.txt';
      Options := [ofPathMustExist, ofFileMustExist];
      if Execute then
        ListBox1.Items.LoadFromFile(FileName);
    finally
      Free;
    end;

  FirstInvalidIndex := -1;
  ListBox1.Items.BeginUpdate;
  try
    for i := 0 to ListBox1.Count - 1 do
      if not TryStrToInt(ListBox1.Items[i], dummy) then
      begin
        ListBox1.Items.Objects[i] := TObject(1);
        if FirstInvalidIndex = -1 then
          FirstInvalidIndex := i;
      end;
  finally
    ListBox1.Items.EndUpdate;
  end;

  if FirstInvalidIndex <> -1 then
  begin
    ListBox1.ItemIndex := FirstInvalidIndex;
    MessageBox(Handle, 'An invalid row was found.', PChar(Caption), MB_ICONERROR);
  end;

end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
var
  ListBox: TListBox;
  Canvas: TCanvas;
  S: string;
begin
  ListBox := Control as TListBox;
  Canvas := ListBox.Canvas;

  Canvas.Font.Assign(ListBox.Font);

  if odSelected in State then
  begin
    Canvas.Brush.Color := clHighlight;
    Canvas.Font.Color := clHighlightText;
  end
  else
  begin
    Canvas.Brush.Color := clWindow;
    Canvas.Font.Color := clWindowText;
  end;

  if ListBox.Items.Objects[Index] = TObject(1) then
  begin
    Canvas.Font.Color := clRed;
    Canvas.Font.Style := [fsBold, fsStrikeOut]
  end;

  Canvas.FillRect(Rect);
  S := ListBox.Items[Index];
  Canvas.TextRect(Rect, S, [tfSingleLine, tfVerticalCenter]);

end;
procedure TForm1.按钮1点击(发送方:TObject);
变量
i、 dummy,FirstInvalidIndex:整数;
开始
使用TOpenDialog.Create(Self)do
尝试
过滤器:='文本文件(*.txt)|*.txt';
选项:=[路径必须存在,路径必须存在];
如果执行,那么
ListBox1.Items.LoadFromFile(文件名);
最后
自由的
结束;
FirstInvalidIndex:=-1;
ListBox1.Items.BeginUpdate;
尝试
对于i:=0到ListBox1.Count-1 do
如果不是TryStrToInt(ListBox1.Items[i],dummy),则
开始
ListBox1.Items.Objects[i]:=TObject(1);
如果FirstInvalidIndex=-1,则
FirstInvalidIndex:=i;
结束;
最后
ListBox1.Items.EndUpdate;
结束;
如果FirstInvalidIndex-1,则
开始
ListBox1.ItemIndex:=FirstInvalidIndex;
MessageBox(句柄“找到无效行”)、PChar(标题)、MB_ICONERROR;
结束;
结束;
过程TForm1.ListBox1DrawItem(控件:TWinControl;索引:Integer;
Rect:TRect;State:TOwnerDrawState);
变量
列表框:TListBox;
画布:TCanvas;
S:字符串;
开始
ListBox:=控件作为TListBox;
Canvas:=ListBox.Canvas;
Canvas.Font.Assign(ListBox.Font);
如果在状态中选择了ODP,则
开始
Canvas.Brush.Color:=clHighlight;
Canvas.Font.Color:=clHighlightText;
结束
其他的
开始
Canvas.Brush.Color:=clWindow;
Canvas.Font.Color:=clWindowText;
结束;
如果ListBox.Items.Objects[Index]=TObject(1),则
开始
Canvas.Font.Color:=clRed;
Canvas.Font.Style:=[fsBold,fsStrikeOut]
结束;
Canvas.FillRect(Rect);
S:=ListBox.Items[索引];
TextRect(Rect,S,[tfSingleLine,tfVerticalCenter]);
结束;

细节:请注意,上面的代码片段只是简单的示例,旨在演示基本方法。在实际应用程序中,您需要更加小心细节。例如,如果背景颜色是系统颜色,则不能使用硬编码的红色文本颜色(因为该颜色也可能是红色!)


此外,如果文本文件是空的(试试!),会发生什么情况?

#安德烈亚斯·雷杰布兰德:你说得对。你说得有道理。但在我的真实代码(不是我给出的伪代码)中,我会检查空行。我希望问题尽可能简短,所以我省略了很多检查(尝试-除了-最后-作为其中一个)。我一直在外地,所以我无法检查/尝试代码。我今天晚些时候再做,晚些时候再回来。无论如何,非常感谢你的代码和评论。
type
  TItemFormat = class
    BackgroundColor: TColor;
    TextColor: TColor;
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  ItemFormat: TItemFormat;
begin

  ListBox1.Items.BeginUpdate;
  try
    ListBox1.Clear;
    for i := 1 to 100 do
    begin
      ItemFormat := TItemFormat.Create;
      ItemFormat.BackgroundColor := IfThen(Odd(i), clSkyBlue, clMoneyGreen);
      ItemFormat.TextColor := IfThen(Odd(i), clNavy, clGreen);
      ListBox1.Items.AddObject(i.ToString, ItemFormat);
    end;
  finally
    ListBox1.Items.EndUpdate;
  end;

end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
var
  ListBox: TListBox;
  Canvas: TCanvas;
  ItemFormat: TItemFormat;
  S: string;
begin
  ListBox := Control as TListBox;
  Canvas := ListBox.Canvas;
  ItemFormat := ListBox.Items.Objects[Index] as TItemFormat;

  Canvas.Brush.Color := ItemFormat.BackgroundColor;
  Canvas.FillRect(Rect);
  S := ListBox.Items[Index];
  Canvas.Font.Color := ItemFormat.TextColor;
  Canvas.TextRect(Rect, S, [tfSingleLine, tfVerticalCenter]);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
  i, dummy, FirstInvalidIndex: Integer;
begin

  with TOpenDialog.Create(Self) do
    try
      Filter := 'Text files (*.txt)|*.txt';
      Options := [ofPathMustExist, ofFileMustExist];
      if Execute then
        ListBox1.Items.LoadFromFile(FileName);
    finally
      Free;
    end;

  FirstInvalidIndex := -1;
  ListBox1.Items.BeginUpdate;
  try
    for i := 0 to ListBox1.Count - 1 do
      if not TryStrToInt(ListBox1.Items[i], dummy) then
      begin
        ListBox1.Items.Objects[i] := TObject(1);
        if FirstInvalidIndex = -1 then
          FirstInvalidIndex := i;
      end;
  finally
    ListBox1.Items.EndUpdate;
  end;

  if FirstInvalidIndex <> -1 then
  begin
    ListBox1.ItemIndex := FirstInvalidIndex;
    MessageBox(Handle, 'An invalid row was found.', PChar(Caption), MB_ICONERROR);
  end;

end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
var
  ListBox: TListBox;
  Canvas: TCanvas;
  S: string;
begin
  ListBox := Control as TListBox;
  Canvas := ListBox.Canvas;

  Canvas.Font.Assign(ListBox.Font);

  if odSelected in State then
  begin
    Canvas.Brush.Color := clHighlight;
    Canvas.Font.Color := clHighlightText;
  end
  else
  begin
    Canvas.Brush.Color := clWindow;
    Canvas.Font.Color := clWindowText;
  end;

  if ListBox.Items.Objects[Index] = TObject(1) then
  begin
    Canvas.Font.Color := clRed;
    Canvas.Font.Style := [fsBold, fsStrikeOut]
  end;

  Canvas.FillRect(Rect);
  S := ListBox.Items[Index];
  Canvas.TextRect(Rect, S, [tfSingleLine, tfVerticalCenter]);

end;