【问题标题】:How to search a FMX.TListView header as well as items如何搜索 FMX.TListView 标头以及项目
【发布时间】:2019-12-30 03:52:55
【问题描述】:

我有一个 LiveBindings 数据绑定 FMX.TListView,其中 FieldName 为 Stage,FillHeaderFieldName 为 Production。当应用程序运行时,我会看到一个使用 HeaderAppearance 的 Productions 列表,并且在每个 Production 中,都有一个使用 ItemAppearance 的 Stages 列表。我已打开 SearchVisible 以使组件搜索面板显示在列表顶部。

目前,在搜索框中输入内容仅过滤舞台,而不是制作。

我希望能够同时做到这两个,并且我希望能够做到这一点,而无需使用过滤器参数进行另一个 REST 调用。我知道我可能需要为 OnSearchChange 事件编写一个事件处理程序,并且我有这段代码来获取输入的搜索文本:

  List := Sender as TListView;

  for I := 0 to List.Controls.Count-1 do
    if List.Controls[I].ClassType = TSearchBox then
    begin
      SearchBox := TSearchBox(List.Controls[I]);
      break;
    end;

我认为我需要设置 Items.Filter 属性,我使用了这段代码:

  Lower := LowerCase(SearchBox.Text.Trim);

  List.Items.Filter :=
    function(X: string): Boolean
    begin
      Result:= (Lower = EmptyStr) or LowerCase(X).Contains(Lower);
    end;

其中一个问题是 ListView 组件在输入字符后立即应用其过滤,而 OnSearchChange 事件仅在搜索框失去焦点时触发。

第二个问题是,即使在事件被触发并设置了新的过滤器函数之后,列表也没有任何反应。

我已经确认我的“36”示例中的 List.Items 集合确实包含所有 6 个项目 - 3 个标题项目和 3 个详细项目 - 所以我不确定为什么过滤器不适用于标题项目,因为它适用于详细信息项目。

【问题讨论】:

  • 我想我已经完成了您正在寻找的事情,但我找不到代码。我向数据集添加了一个计算字段,该字段连接了我想要过滤列表视图的所有字段(使用不可能的分隔符,如管道字符)。然后我将该字段绑定到列表视图以进行搜索。列表视图实际上有一个自定义布局,其中有几个字段位于不同的位置、字体、大小等......但我想过滤所有这些。但用于搜索 IIRC 的字段不一定要显示。
  • @Frazz。谢谢。我会试一试的。添加一个包含 Production 和 Stage 文本的隐藏字段,然后将其设置为搜索字段...如果我知道该怎么做的话。我只能推测内置搜索仅适用于在 LiveBindings 下选择为 FieldName 的任何内容(或查看 Bind Visually 图表时的 Item.Text ...)
  • 好吧。在这方面没有取得任何进展。找不到有关如何在任何字段上进行 LiveBindings TListView 搜索的任何文档,除了为项目选择的字段。我什至不能向 Embarcadero 寻求开发支持,因为他们只是把我送到他们的 Idera 社区论坛(我也发过帖子)。我想我最终可能不得不删除 Live Bindings 并手动填充 TListView,但这会慢很多。

标签: delphi firemonkey delphi-10.3-rio


【解决方案1】:

我尝试了这个并找到了解决方案。请记住,我无法访问 Delphi 10.3 Rio。我正在使用 10.1 柏林。还要记住,我通常做的是在代码中绑定,而不是在视觉上。但为此我坚持使用视觉绑定。

作为数据集,我使用了 TFDMemoryTable (mt1),其中包含 2 个数据字段(fmt1Prod 和 fmt1Stage)和 1 个计算字段(fmt1Search)。我有以下处理程序来计算搜索字段:

Procedure TForm2.mt1CalcFields(DataSet: TDataSet);
Begin
  fmt1Search.AsString := fmt1Prod.AsString + '|' + fmt1Stage.AsString;
End;

我在内存表 OnFormCreate 中放了一些随机数据:

Procedure TForm2.FormCreate(Sender: TObject);
Var
  i1, i2: Integer;
  s1, s2: String;
Begin
  mt1.CreateDataSet;
  For i1   := 1 To 13 Do Begin
    s1     := 'Prod' + FormatFloat('00', i1);
    For i2 := Random(6) To Random(14) Do Begin
      s2   := 'Stage' + FormatFloat('00', i2);
      mt1.Append;
      fmt1Prod.AsString  := s1;
      fmt1Stage.AsString := s2;
      mt1.Post;
    End;
  End;
End;

我在 Form2 上放了一个 TGrid 和一个 TListView。两者都绑定到数据集。数据和计算字段在 TGrid 中正确显示(只是为了检查)。

TListView 绑定到数据集如下:

Synch            <-> *
ItemHeader.Text  <-  Prod
ItemHeader.Break <-  Prod
Item.Text        <-  Search
Item.Detail      <-  Stage

我这样做是因为我找不到让 TListView 搜索框在除项目文本之外的任何内容上工作的方法。好吧……但这可以解决:

  • 将 TListView.ItemAppeance 设置为自定义
  • 在结构中找到 TListView/ItemAppearance/Item/Text 对象并将 Visible 设置为 False
  • 在结构体中找到 TListView/ItemAppearance/Item/Detail 对象,并将 Visible 设置为 True

我不确定以上所有内容都是必要的,但它确实有效。如果您的 TListView 是可编辑的,那么您可能也需要修改 ItemEditAppearance。

请记住,使用自定义项目外观,您实际上可以将列表视图项目设置为您想要的任何外观。您可以添加和删除标签、图像和其他内容。它没有设计表单那么强大,但你可以用它做很多事情。但您真正需要的只是隐藏搜索文本并在项目的某处显示舞台文本。

而且...对于更复杂的项目外观,您可能需要进行一些代码绑定(虽然不确定)。

【讨论】:

  • 谢谢@Frazz。今天无法通过你的答案,但我会在星期一。我喜欢将显示项目更改为自定义外观并隐藏搜索正在查看的实际项目的想法。如果可行,我一定会接受你的回答。
  • 完美@Frazz。向我的存储类添加了一个新属性,将字段添加到 TDataGeneratorAdapter,从 TListView 进行了可视化绑定(如上所述设置属性),现在它可以完美运行了。
  • 在 iOS 上除外,如果输入的搜索文本没有结果,则在 TListView.iOS 代码中生成“参数超出范围”错误并使应用程序崩溃。目前我们已经关闭了 iOS 设备的搜索功能。
  • 我没有使用 iOS 的经验……但这似乎是一个可能的错误。如果您可以隔离它发生的位置,您可能需要在 Embarcadero 质量中心开一张票。带有搜索框的普通 iOS 列表视图是否显示相同的错误?
  • 这就是我一直在尝试做的。为 QC 获取一个简单的可重现示例,以添加到我创建的 JIRA 问题中。但是,如果我在 iOS 模拟器中运行我的示例,它是可以的,但我无法使用通过 TestFlight 将它部署到设备,因为没有配置示例应用程序。最终我会回到它,但我真的不能花费一天的大部分时间来寻找最有可能是 FireMonkey iOS 问题的修复程序或解决方法。
【解决方案2】:

如果使用视觉绑定和 ItemAppearance(动态外观),您可以将数据源中的一列分配给标题和文本项(可见 = false)。在这种情况下,在标题和项目中我们具有相同的值并且搜索工作正常。

【讨论】:

    猜你喜欢
    • 2015-06-08
    • 2019-06-13
    • 2015-01-24
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    相关资源
    最近更新 更多