delphi - 颜色 Listbox.Item[N] 其中 N 由代码生成
问题描述
我有一个列表框。我使用以下文件填充它:
IF Opendialog1.Execute then
BEGIN
Listbox1.Items.LoadfromFile(OpenDialog1.FileName);
END;
加载的文件包含数字,并且仅包含数字(我假设)。是100 pct。当然,我现在开始扫描:(伪代码 :)
for N := 0 til Listbox1.Items.Count -1 DO
BEGIN
NUM := ScanForNotNumberInListbox1Item(Listbox1.Items[N]);
//
// returns NUM = -1 if non digit is met..
//
IF NUM <> 0 then
begin
LISTBOX1.Items[N].BackGroundColor := RED;
Exit; (* or terminate *)
END;
END;
我知道我必须使用 LIstbox1.DrawItem (); 并尝试了 Stack Exchange 中显示的示例,但似乎没有一个使用的示例是代码生成的。
那么我该怎么做呢?
克里斯
解决方案
介绍
您可以将有关每个列表项的附加信息存储在其关联的“对象”中。这可以是一个(指向一个)真实对象的指针,或者您可以使用这个指针大小的整数来编码您想要的任何简单信息。
举个简单的例子,让我们将项目的背景颜色放在这个字段 ( uses Math
) 中:
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
ListBox1.Items.BeginUpdate;
try
ListBox1.Clear;
for i := 1 to 100 do
ListBox1.Items.AddObject(i.ToString, TObject(IfThen(Odd(i), clSkyBlue, clMoneyGreen)));
finally
ListBox1.Items.EndUpdate;
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.Brush.Color := TColor(ListBox.Items.Objects[Index]);
Canvas.FillRect(Rect);
S := ListBox.Items[Index];
Canvas.TextRect(Rect, S, [tfSingleLine, tfVerticalCenter]);
end;
不要忘记将列表框的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;
细则:请注意,上面的代码片段只是用于演示基本方法的简单示例。在实际应用中,您需要更加注意细节。例如,如果背景颜色是系统颜色,则不能使用硬编码的红色文本颜色(因为该颜色很可能也是红色!)。
另外,如果文本文件是空的会发生什么(试试看!)?
推荐阅读
- json - 使用 Python 将 Jira Json 转换为数据框。一列保留为json的问题
- javascript - 如何清除被嘲笑的剧作家回应?
- ios - 将视频上传到云存储时出错,但不是图像 (Swift/Xcode/iOS)
- php - 运算符“===”在对象中使用时无法正确评估,因为它应该 php
- python - 如何从 Treeview / Tkinter (SQLite) 中的不同表中获取不同的值?
- python - 为什么 hist2d 绘制 UNIFORM 密度图?
- python - 我如何压缩所有这些“if”语句?
- azure-devops - 在 Azure DevOps 测试结果中查看单元测试说明
- android - ExposedDropdownMenu 中的字符串以外的其他对象
- javascript - 使用highchart在柱形图中获取一系列的一系列