Delphi 12.0中Firemonkey TListview绑定数据集单条刷新问题
Delphi 12 FireMonkey TListView 单行刷新解决方案
针对已知修改行的ItemIndex,可以通过以下两种优雅方式实现单行刷新,无需全量更新列表或手动赋值:
方法一:直接刷新单行绑定控件
利用现有LiveBindings的TLinkControlToField组件,仅更新目标行的绑定控件数据,复用原有绑定逻辑:
procedure RefreshSingleListViewItem(AListView: TListView; AItemIndex: Integer); var LItem: TListViewItem; I: Integer; LLink: TLinkControlToField; begin if (AListView = nil) or (AItemIndex < 0) or (AItemIndex >= AListView.Items.Count) then Exit; LItem := AListView.Items[AItemIndex]; // 遍历Item内所有绑定控件,强制同步最新数据 for I := 0 to LItem.ControlsCount - 1 do begin if LItem.Controls[I] is TLinkControlToField then begin LLink := TLinkControlToField(LItem.Controls[I]); // 调用UpdateControlValue直接同步数据集当前值到控件,比切换Active更高效 LLink.UpdateControlValue; end; end; // 标记Item重绘,确保界面更新 LItem.InvalidateRect(LItem.BoundsRect); end;
方法二:通过绑定适配器触发单行更新
借助LiveBindings的适配器机制,通知数据源指定项已变更,让绑定系统自动更新对应行:
procedure RefreshListViewItemViaAdapter(AListView: TListView; AItemIndex: Integer; ADataset: TDataset); var LBindAdapter: TBindListAdapter; LSourceAdapter: TListBindSourceAdapter; begin if (AListView = nil) or (ADataset = nil) or (AItemIndex < 0) then Exit; // 获取ListView绑定的适配器 if AListView.BindingList is TBindListAdapter then begin LBindAdapter := TBindListAdapter(AListView.BindingList); if LBindAdapter.Source is TListBindSourceAdapter then begin LSourceAdapter := TListBindSourceAdapter(LBindAdapter.Source); // 定位到数据集对应记录(注意RecNo从1开始,ItemIndex从0开始) ADataset.RecNo := AItemIndex + 1; // 通知适配器指定位置数据变更,触发绑定更新 LSourceAdapter.ItemChanged(AItemIndex); // 重绘Item完成界面刷新 AListView.Items[AItemIndex].Invalidate; end; end; end;
注意事项
- 调用前需确保数据集已保存修改,且记录指针可正常定位到目标行
- 方法二更贴合LiveBindings的设计逻辑,无需遍历控件,适配不同结构的ListView
- 两种方法均仅针对单行操作,避免大数据集下全量刷新的性能损耗
内容的提问来源于stack exchange,提问作者Peter Jones
相关产品推荐
相关产品推荐

