Delphi 将项目从StringList加载到ComboBox,并根据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,

我按排序顺序将项目从StringList加载到组合框。当我在组合框中选择一个项目时,我想知道该项目在StringList中出现的相应顺序

例如: StringList的第一项是FFFFF,但这是组合框中的最后一项。因此,当在组合框中选择FFFFF时,我的程序需要告诉我它是StringList中的最后一项

这是我的程序,编译得很好,但它没有显示所需的结果,我无法找到错误

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;