首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ListBoxItem可见错误

ListBoxItem可见错误
EN

Stack Overflow用户
提问于 2017-10-14 20:50:08
回答 1查看 940关注 0票数 1

在东京的Delphi10.2中,我对TListBox和TListBoxItem有一些不理解的地方。

一些值(TListBoxItem)被加载到我的ListBox中,当第一个字母改变时,我添加了一个TListBoxGroupHeader。

代码语言:javascript
复制
procedure TForm1.Button1Click(Sender: TObject);
var
   lbItem: TListBoxItem;
   Letter: string;
   ListBoxGroupHeader: TListBoxGroupHeader;
   i: integer;
   ListValue: TStringList;
begin
   Letter := '';

   ListValue := TStringList.Create;
   try
      ListValue.Add('Germany');
      ListValue.Add('Georgie');
      ListValue.Add('France');
      ListValue.Add('Venezuela');
      ListValue.Add('Poland');
      ListValue.Add('Russia');
      ListValue.Add('Sweden');
      ListValue.Add('Denmark');

      ListBox1.BeginUpdate;

      for i := 0 to ListValue.Count - 1 do
      begin
         if Letter <> Copy(ListValue[i], 0, 1).ToUpper then
         begin
            ListBoxGroupHeader        := TListBoxGroupHeader.Create(ListBox1);
            ListBoxGroupHeader.Text   := Copy(ListValue[i], 0, 1).ToUpper;
            ListBox1.AddObject(ListBoxGroupHeader);
         end;

         lbItem := TListBoxItem.Create(ListBox1);
         lbItem.Text   := ListValue[i];
         lbItem.Tag    := i;

         ListBox1.AddObject(lbItem);
         Letter := Copy(ListValue[i], 0, 1).ToUpper;
      end;

   finally
      ListBox1.EndUpdate; 
      FreeAndNil(ListValue);
   end;
end;

我使用TEdit在这个ListBox中进行搜索。这就是我的问题所在。如果ListBoxItem包含我设置为True的Edit的内容,否则我将其设置为False。

代码语言:javascript
复制
procedure TForm1.Edit1ChangeTracking(Sender: TObject);
var
   i           : integer;
   ListBoxItem: TListBoxItem;
begin
   ListBox1.BeginUpdate;
   try
      for i := 0 to ListBox1.Items.Count - 1 do
      begin
         if ListBox1.ListItems[i] is TListBoxItem then
         begin
            ListBoxItem := TListBoxItem(ListBox1.ListItems[i]);

            if Edit1.Text.Trim = '' then
            begin
               ListBoxItem.Visible := True
            end
            else
            begin
               if ListBox1.ListItems[i] is TListBoxGroupHeader then
                  ListBoxItem.Visible := False
               else
                  ListBoxItem.Visible := ListBoxItem.Text.ToLower.Contains(Edit1.Text.Trim.ToLower);
            end;
         end;
      end;
   finally
      ListBox1.EndUpdate;
   end;
end;

第一个GroupHeader (字母G)总是可见的!看起来像是在GroupHeader后面有一个ListBoxItem。当我使用检查点时,可见设置为false ..所以我不明白..

如果我写字母"V“,我只能看到带有字母"G”的GroupHeader。

我让evene尝试更改文本值,如果它是一个GroupHeader。

代码语言:javascript
复制
if ListBox1.ListItems[i] is TListBoxGroupHeader then
   ListBoxItem.Text := '>>' + ListBoxItem.Text + '<<'   

这是更改文本,但不是第一个GroupHeader (字母G) ...

不知道是我用得不好,还是它是个bug?

EN

回答 1

Stack Overflow用户

发布于 2017-10-16 20:36:32

我可以重现你所描述的,这与隐藏标题,同时保持标题下的项目可见有关。在这种情况下,应用程序显示标题而不是项目。我还没有检查里面有什么问题,但似乎不是你想要的。我想保留与搜索文本匹配的可见项目及其各自的标题,并且只隐藏标题而不隐藏标题下的项目。

如果是这样的话,试试这个:

代码语言:javascript
复制
procedure FilterItems(const Text: string; ListBox: TListBox);
var
  I: Integer; { ← loop variable }
  Hide: Boolean; { ← flag indicating if we want to hide the last header we passed }
  Item: TListBoxItem; { ← currently iterated item }
  Head: TListBoxGroupHeader; { ← last header item we passed during iteration }
begin
  Head := nil;
  Hide := True;

  ListBox.BeginUpdate;
  try
    { if search text is empty, show all items }
    if Text.IsEmpty then
      for I := 0 to ListBox.Content.ControlsCount - 1 do
        ListBox.ListItems[I].Visible := True
    else
    { otherwise compare text in non header items }
    begin
      for I := 0 to ListBox.Content.ControlsCount - 1 do
      begin
        Item := ListBox.ListItems[I];
        { if the iterated item is header }
        if Item is TListBoxGroupHeader then
        begin
          { set the previous header visibility by at least one visible item }
          if Assigned(Head) then
            Head.Visible := not Hide;
          { assume hiding this header and store its reference }
          Hide := True;
          Head := TListBoxGroupHeader(Item);
        end
        else
        { if the iterated item is a regular item }
        if Item is TListBoxItem then
        begin
          { set the item visibility by matching text; if the item remains visible, it
            means we don't want to hide the header, so set our flag variable as well }
          if Item.Text.ToLower.Contains(Text) then
          begin
            Hide := False;
            Item.Visible := True;
          end
          else
            Item.Visible := False;
        end;
      end;
      { the iteration finished, so now setup visibility of the last header we passed }
      if Assigned(Head) then
        Head.Visible := not Hide;
    end;
  finally
    ListBox.EndUpdate;
  end;
end;

procedure TForm1.Edit1ChangeTracking(Sender: TObject);
begin
  FilterItems(Edit1.Text.Trim.ToLower, ListBox1);
end;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46744770

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档