【问题标题】:delphi and the displaying of a listbox itemsdelphi 和列表框项目的显示
【发布时间】:2011-03-15 12:25:17
【问题描述】:

我正在使用一个列表框来显示一个简单的文件名列表。我还有一个编辑组件,允许我通过简单的方式搜索这些项目:

procedure TForm1.Edit1Change(Sender: TObject);
const
  indexStart = -1;
var
  search : array[0..256] of Char;
begin
  if edit1.Text='' then exit;
  StrPCopy(search, Edit1.Text) ;
  ListBox1.ItemIndex := ListBox1.Perform(LB_SELECTSTRING, indexStart, LongInt(@search));
end;

现在,有没有办法“有选择地”在列表框中显示项目?我的意思是,如果我搜索以“hello”开头的项目,那么只会显示那些会打招呼的项目,要么将它们变暗而不是不显示,要么完全显示 := false。 有没有办法使用列表框来执行此操作?

谢谢!

哦,这是 Delphi 7...

【问题讨论】:

    标签: delphi listbox


    【解决方案1】:

    我总是这样做(而且我经常这样做):

    我有一个包含列表框项目的array of stringTStringList。然后,在 Edit1Change 中清除 Items 属性并仅添加与编辑框中的文本匹配的字符串。

    字符串数组

    如果您使用字符串数组,例如

    var
      arr: array of string;
    

    以某种方式初始化,如

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      SetLength(arr, 3);
      arr[0] := 'cat';
      arr[1] := 'dog';
      arr[2] := 'horse';
    end;
    

    那你就可以了

    procedure TForm1.Edit1Change(Sender: TObject);
    var
      i: Integer;
    begin
      ListBox1.Items.BeginUpdate;
      ListBox1.Items.Clear;
      if length(Edit1.Text) = 0 then
        for i := 0 to high(arr) do
          ListBox1.Items.Add(arr[i])
      else
        for i := 0 to high(arr) do
          if Pos(Edit1.Text, arr[i]) > 0 then
            ListBox1.Items.Add(arr[i]);
      ListBox1.Items.EndUpdate;
    end;
    

    这将只显示数组中包含 Edit1.Text 的那些字符串;字符串不需要以Edit1.Text开始。为此,请替换

    Pos(Edit1.Text, arr[i]) > 0
    

    Pos(Edit1.Text, arr[i]) = 1
    

    TStringList

    如果是TStringList,如

    var
      arr: TStringList;
    

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      arr := TStringList.Create;
      arr.Add('cat');
      arr.Add('dog');
      arr.Add('horse');
    end;
    

    你可以的

    procedure TForm1.Edit1Change(Sender: TObject);
    var
      i: Integer;
    begin
      ListBox1.Items.BeginUpdate;
      ListBox1.Items.Clear;
      if length(Edit1.Text) = 0 then
        ListBox1.Items.AddStrings(arr)
      else
        for i := 0 to arr.Count - 1 do
          if Pos(Edit1.Text, arr[i]) = 1 then
            ListBox1.Items.Add(arr[i]);
      ListBox1.Items.EndUpdate;
    end;
    

    区分大小写

    上面的代码使用区分大小写的匹配,例如“bo”不会匹配“Boston”。为了让代码对大小写不敏感,写

    if Pos(AnsiLowerCase(Edit1.Text), AnsiLowerCase(arr[i])) > 0 then
    

    而不是

    if Pos(Edit1.Text, arr[i]) > 0 then
    

    【讨论】:

    • 这可能有效。我看到的问题是我不知道列表框中有多少项目。它不固定。很难用 SetLength 设置数组的大小。除非...我可以稍后使用 SetLength 来重置数组的长度吗?还是使用 TStringList 更好?
    • 大多数人总是使用TStringList,但我个人想手动完成所有操作,所以我总是使用array of string。您可以随时通过SetLength 更改动态数组的长度。如果您增加长度,旧项目仍然存在。
    • 嗯。我正在尝试使用 tliststring。当我尝试搜索时,所有项目都消失了。哦,我的错,我加载错了......但是它不起作用。我有 2 个文件,名为:book 1 和 book 2。当我搜索 book 时,它会找到名为“places in boston”的文件的“bo”,仅此而已
    • 知道了,我只是将 Lowercase() 添加到 Pos(Lowercase(Edit1.Text), Lowercase(arr[i])) 以使其不区分大小写。谢谢!
    • @Uri:是的,我认为这是问题所在,所以我什至更新了我的答案!
    【解决方案2】:

    您所要求的可以通过将标准 Win32 API IAutoComplete 接口连接到标准 TEdit 来实现,不需要 TListBox。将 TStrings 对象连接到 IAutoComplete 并不难,因此它知道哪些字符串可用于搜索。

    【讨论】:

      猜你喜欢
      • 2012-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 2016-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多