FMX TComboBox通过LiveBindings绑定ClientDataset过滤后下拉列表显示不更新
我有一个通过LiveBindings绑定到ClientDataset的FMX ComboBox控件,此前运行一切正常,直到我需要对ClientDataset的数据进行过滤。应用过滤规则后,ComboBox.Items和ComboBox.ListItems的内容均正确,对应过滤后的ClientDataset数据,但ComboBox下拉列表展示的数据始终为首次展示时ClientDataset的原始数据,未同步更新。
示例代码如下:
procedure TForm14.Button1Click(Sender: TObject); begin LinkFillControlToField1.Active := False; ClientDataset1.Filter := 'TYPE = ''N'''; Clientdataset1.Filtered := not ClientDataset1.Filtered; // 停用后重新启用绑定链接是刷新数据的常用操作 LinkFillControlToField1.Active := True; end;
上述代码中,我修改了ClientDataset的过滤条件,先停用LinkFillControlToField,应用过滤后再重新启用以刷新数据。该方案在TListBox等其他控件上运行正常,但在TComboBox上无效:尽管ComboBox.Items和ComboBox.ListItems已经包含正确数据,但下拉列表展示内容并未同步更新。
请问是否有基于LiveBindings的解决方案?我已尝试调用ComboBox的Repaint等方法、调整LinkFillControlToField和BindSourceDB的属性及方法,均无效果。
开发环境为Delphi 10.4 Update 2,运行在Windows 10系统上的Firemonkey Windows应用(支持32位/64位)。
该问题是Delphi 10.4 Update 2版本FMX框架的已知缺陷,核心是TComboBox内部维护了独立的下拉渲染缓存,没有响应LiveBindings触发的列表项变更通知,TListBox等控件没有这层额外缓存所以可以正常刷新。以下是完全基于LiveBindings的解决方案,不需要破坏原有绑定逻辑:
方案1:调用绑定填充方法(优先使用)
直接调用LinkFillControlToField的公开填充方法触发全量更新,无需手动开关绑定链接:
procedure TForm14.Button1Click(Sender: TObject); begin // 更新数据集过滤规则 ClientDataset1.Filter := 'TYPE = ''N'''; ClientDataset1.Filtered := not ClientDataset1.Filtered; // 触发LiveBindings全量填充控件列表 LinkFillControlToField1.Fill; // 同步控件当前选中值与数据集状态,避免选中项丢失 LinkFillControlToField1.UpdateControl; end;
方案2:配置属性实现自动刷新
如果需要多处触发过滤,可直接修改设计期属性实现无代码自动刷新:
- 将
LinkFillControlToField.AutoFill属性设置为True - 将
BindSourceDB.AutoRefresh属性设置为True
后续只要修改ClientDataset的过滤规则并提交,LiveBindings会自动触发ComboBox的列表更新,不需要额外编写逻辑。
兜底兼容方案
如果上述方案仍无效,可在重新激活绑定链接后加一行代码强制清空ComboBox内部缓存,不需要直接操作Items内容:
// 加在LinkFillControlToField1.Active := True;之后 ComboBox1.DropDownCount := ComboBox1.DropDownCount;
这行代码通过重新赋值下拉列表显示行数,触发ComboBox内部重建下拉渲染项,不会破坏原有LiveBindings绑定逻辑。
内容的提问来源于stack exchange,提问作者Ricardo

