Delphi 将项目从StringList加载到ComboBox,并根据StringList进行选择
我按排序顺序将项目从StringList加载到组合框。当我在组合框中选择一个项目时,我想知道该项目在StringList中出现的相应顺序 例如: StringList的第一项是FFFFF,但这是组合框中的最后一项。因此,当在组合框中选择FFFFF时,我的程序需要告诉我它是StringList中的最后一项 这是我的程序,编译得很好,但它没有显示所需的结果,我无法找到错误Delphi 将项目从StringList加载到ComboBox,并根据StringList进行选择,delphi,delphi-xe2,Delphi,Delphi Xe2,我按排序顺序将项目从StringList加载到组合框。当我在组合框中选择一个项目时,我想知道该项目在StringList中出现的相应顺序 例如: StringList的第一项是FFFFF,但这是组合框中的最后一项。因此,当在组合框中选择FFFFF时,我的程序需要告诉我它是StringList中的最后一项 这是我的程序,编译得很好,但它没有显示所需的结果,我无法找到错误 unit Unit1; interface uses Winapi.Windows, Winapi.Messages,
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons;
type
TForm1 = class(TForm)
ComboBox1: TComboBox;
Edit1: TEdit;
BitBtn1: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var ItemList : TStringList;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if ComboBox1.ItemIndex = -1
then
begin
Edit1.Text := 'Select Items';
end
else if ComboBox1.ItemIndex <> -1
then
begin
if ComboBox1.ItemIndex = ComboBox1.Items.IndexOf('ItemList.IndexOf(0)')
then
begin
Edit1.Text := 'First Line Selected'
end
else if ComboBox1.ItemIndex = ComboBox1.Items.IndexOf('ItemList.IndexOf(1)')
then
begin
Edit1.Text := 'Second Line Selected'
end
else if ComboBox1.ItemIndex = ComboBox1.Items.IndexOf('ItemList.IndexOf(2)')
then
begin
Edit1.Text := 'Third Line Selected'
end
else if ComboBox1.ItemIndex = ComboBox1.Items.IndexOf('ItemList.IndexOf(3)')
then
begin
Edit1.Text := 'Forth Line Selected'
end
else if ComboBox1.ItemIndex = ComboBox1.Items.IndexOf('ItemList.IndexOf(4)')
then
begin
Edit1.Text := 'Fifth Line Selected'
end
else if ComboBox1.ItemIndex = ComboBox1.Items.IndexOf('ItemList.IndexOf(5)')
then
begin
Edit1.Text := 'Sixth Line Selected'
end
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ItemList.Clear;
ItemList.Free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ComboBox1.Sorted := true;
ItemList := TStringList.Create;
with ItemList do
begin
Add('FFFFF');
Add('EEEEE');
Add('DDDDD');
Add('CCCCC');
Add('BBBBB');
Add('AAAAA');
end;
ComboBox1.Items.BeginUpdate;
try
begin
ComboBox1.Items.AddStrings(ItemList);
end
finally
begin
ComboBox1.Items.EndUpdate;
end
end;
end;
end.
识别问题
在这里,您将研究组合框中所选项目的索引是否等于组合框项目中文本“ItemList.IndexOf0”的索引。您可以让组合框在其项中搜索字符串“ItemList.IndexOf0”。您只添加了“FFFFF”…'AAAAA',因此字符串“ItemList.IndexOf0”不会出现在组合框中。因此将返回-1
ComboBox中的选定项索引为0到5,因为共有六个项,从0开始,因此ComboBox1.ItemIndex将不为-1,因此该等式结果为False。其他五个类似的if语句也是如此。这就是编辑框未按预期方式更新的原因
解决方案:
将所选组合框项目与StringList项目列表中的所有项目进行比较:
这段包含七条if语句的代码可以重构为:
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
case ItemList.IndexOf(ComboBox1.Text) of
0: Edit1.Text := 'First line Selected';
1: Edit1.Text := 'Second line Selected';
2: Edit1.Text := 'Third line Selected';
3: Edit1.Text := 'Fourth line Selected';
4: Edit1.Text := 'Fifth line Selected';
5: Edit1.Text := 'Sixth line Selected';
else
Edit1.Text := 'Select items';
end;
end;
或者,您可以将其参数化为一个if语句:
procedure TForm1.BitBtn1Click(Sender: TObject);
const
OrderStrings: array[0..5] of String = ('First', 'Second', 'Third', 'Fourth',
'Fifth', 'Sixth');
begin
if ComboBox1.ItemIndex = -1 then
Edit1.Text := 'Select items'
else
Edit1.Text := Format('%s line selected',
[OrderStrings[ItemList.IndexOf(ComboBox1.Text)]]);
end;
在这种情况下,我会将TStringList索引直接存储在TComboBox本身中,然后在需要时使用它们,例如:
procedure TForm1.FormCreate(Sender: TObject);
var
I: Integer;
begin
ComboBox1.Sorted := true;
ItemList := TStringList.Create;
ItemList.Add('FFFFF');
ItemList.Add('EEEEE');
ItemList.Add('DDDDD');
ItemList.Add('CCCCC');
ItemList.Add('BBBBB');
ItemList.Add('AAAAA');
ComboBox1.Items.BeginUpdate;
try
for I := 0 to ItemList.Count-1 do begin
ComboBox1.Items.AddObject(ItemList[I], TObject(I));
end;
finally
ComboBox1.Items.EndUpdate;
end;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
var
Idx: Integer;
begin
Idx := ComboBox1.ItemIndex;
if Idx = -1 then begin
Edit1.Text := 'Select Items';
end else
begin
case Integer(ComboBox1.Items.Objects[Idx]) of
0: Edit1.Text := 'First Line Selected';
1: Edit1.Text := 'Second Line Selected';
2: Edit1.Text := 'Third Line Selected';
3: Edit1.Text := 'Forth Line Selected';
4: Edit1.Text := 'Fifth Line Selected';
5: Edit1.Text := 'Sixth Line Selected';
end;
end;
end;
很难知道您的程序正在做什么,它将要做什么,以及它如何无法满足您的需求。给定组合的内容,对ComboBox1.Items.IndexOf的每次调用都将返回-1。请尝试改进这个问题。是的,它总是返回-1。如果组合框中的所选项目等于TStringList的第一行,那么对第二行执行一些操作,依此类推..我不想使用AAAAA。我想用第一行,第二行的字符串。AAAA可能是多种多样的。它将被更改,然后TSringList将再次更新,ComboBox将相应更新。请不要在评论中添加详细信息。请编辑问题。小备注,ToBeject会在ARC平台上引起问题;此代码是VCL,因此不会在ARC系统上运行。如果需要迁移到ARC,则必须首先将此代码迁移到FireMonkey。但是FireMonkey的TComboBox没有Sorted属性,因此无论如何都必须重新编写此代码才能进行手动排序,在这种情况下,我建议使用查找数组/字典在两个列表之间映射索引。
procedure TForm1.BitBtn1Click(Sender: TObject);
const
OrderStrings: array[0..5] of String = ('First', 'Second', 'Third', 'Fourth',
'Fifth', 'Sixth');
begin
if ComboBox1.ItemIndex = -1 then
Edit1.Text := 'Select items'
else
Edit1.Text := Format('%s line selected',
[OrderStrings[ItemList.IndexOf(ComboBox1.Text)]]);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
I: Integer;
begin
ComboBox1.Sorted := true;
ItemList := TStringList.Create;
ItemList.Add('FFFFF');
ItemList.Add('EEEEE');
ItemList.Add('DDDDD');
ItemList.Add('CCCCC');
ItemList.Add('BBBBB');
ItemList.Add('AAAAA');
ComboBox1.Items.BeginUpdate;
try
for I := 0 to ItemList.Count-1 do begin
ComboBox1.Items.AddObject(ItemList[I], TObject(I));
end;
finally
ComboBox1.Items.EndUpdate;
end;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
var
Idx: Integer;
begin
Idx := ComboBox1.ItemIndex;
if Idx = -1 then begin
Edit1.Text := 'Select Items';
end else
begin
case Integer(ComboBox1.Items.Objects[Idx]) of
0: Edit1.Text := 'First Line Selected';
1: Edit1.Text := 'Second Line Selected';
2: Edit1.Text := 'Third Line Selected';
3: Edit1.Text := 'Forth Line Selected';
4: Edit1.Text := 'Fifth Line Selected';
5: Edit1.Text := 'Sixth Line Selected';
end;
end;
end;