【问题标题】:Loading Items from StringList to ComboBox and selection according to StringList将项目从 StringList 加载到 ComboBox 并根据 StringList 进行选择
【发布时间】:2014-10-13 19:19:09
【问题描述】:

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

例如: 我的StringList 的第一项FFFFF,但那是我的ComboBox 中的最后一项。所以当在 ComboBox 中选择 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.

【问题讨论】:

  • 很难知道你的程序在做什么,它应该做什么,以及它如何不能满足你的需求。给定组合的内容,您对ComboBox1.Items.IndexOf 的每个调用都将返回-1。请尝试改进问题。
  • 是的,它总是返回-1。如果ComboBox 中的选定项目等于TStringListFisrt Line,则执行某些操作并为Second Line 等等..
  • 我不想使用AAAAA。我想使用第一行字符串第二行AAAA 可能是可变的。它将被更改,然后TSringList 将再次更新,ComboBox 将相应更新。
  • 请不要在 cmets 中添加详细信息。请编辑问题。

标签: delphi delphi-xe2


【解决方案1】:

在这种情况下,我会将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;

【讨论】:

  • 小备注,TObject(I) 会在 ARC 平台上造成问题 ;)
  • 这段代码是 VCL,所以它不能在 ARC 系统上运行。如果您需要迁移到 ARC,则必须先将此代码迁移到 FireMonkey。但是 FireMonkey 的 TComboBox 没有 Sorted 属性,因此无论如何都必须重写此代码以进行手动排序,在这种情况下,我建议使用查找数组/字典来映射两个列表之间的索引。
【解决方案2】:

识别问题

    if ComboBox1.ItemIndex = ComboBox1.Items.IndexOf('ItemList.IndexOf(0)') then
    begin
      Edit1.Text := 'First Line Selected'
    end

这里您调查组合框中所选项目的索引是否等于组合框项目中文本'ItemList.IndexOf(0)'的索引。您让 ComboBox 在其项目中搜索字符串 'ItemList.IndexOf(0)'。您只添加了 'FFFFF' .. 'AAAAA',因此字符串 'ItemList.IndexOf(0)' 不会出现在 ComboBox 中.因此ComboBox1.Items.IndexOf() 将返回-1

ComboBox 中的选定项目索引是05(因为有六个项目,从0 开始),所以ComboBox1.ItemIndex 不会是-1,因此这个等式的结果为False。其他五个类似的if-语句也是如此。这就是为什么您的编辑框没有按您预期的方式更新的原因。

解决办法:

将选中的 ComboBox 项与 StringList ItemList 中的所有项进行比较:

    if ComboBox1.Text = ItemList[0] then
    begin
      Edit1.Text := 'First Line Selected'
    end
    else if ComboBox1.Text = ItemList[1] then
    begin
      Edit1.Text := 'Second Line Selected'
    end
    ...

这段带有七个if-statements 的代码可以重构为:

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-statement:

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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多