如何按名称而不是索引访问TDBGrid列?
例如,现在我使用:
grdInvoiceItems.Columns[2].Visible := False;
但是写一些类似的东西会好得多:
grdInvoiceItems.Columns['UnitPrice'].Visible := False;
同时我使用for循环,如:
for idx := 0 to grdInvoiceItems.Columns.Count - 1 do
begin
if (
(grdInvoiceItems.Columns[idx].FieldName = 'UnitPrice') or
(grdInvoiceItems.Columns[idx].FieldName = 'Discount') or
(grdInvoiceItems.Columns[idx].FieldName = 'SecretCode')
) then
grdInvoiceItems.Columns[idx].Visible := False;
end;
使用colum name是IMO更好的tham列索引,因为索引比名称更容易发生变化。
关于如何更好地封装它的任何想法?
答案 0 :(得分:12)
您可以尝试这样的事情:
function ColumnByName(Grid : TDBGrid; const AName : String) : TColumn;
var
i : Integer;
begin
Result := Nil;
for i := 0 to Grid.Columns.Count - 1 do begin
if (Grid.Columns[i].Field <> Nil) and (CompareText(Grid.Columns[i].FieldName, AName) = 0) then begin
Result := Grid.Columns[i];
exit;
end;
end;
end;
当然,如果您使用的是最近版本足以支持Class Helper
的Delphi版本,您可以将此函数包装为Class Helper
TDBGrid
,就像这样
type
TGridHelper = class helper for TDBGrid
function ColumnByName(const AName : String) : TColumn;
end;
[...]
function TGridHelper.ColumnByName(const AName: String): TColumn;
var
i : Integer;
begin
Result := Nil;
for i := 0 to Columns.Count - 1 do begin
if (Columns[i].Field <> Nil) and (CompareText(Columns[i].FieldName, AName) = 0) then begin
Result := Columns[i];
exit;
end;
end;
end;
然后,你可以这样做
Col := DBGrid1.ColumnByName('SomeName');
显然,你可以编写一个类似的函数来搜索列的标题,而不是相关的Field的FieldName。
答案 1 :(得分:1)
您可以在列名和网格索引之间创建映射,例如作为字典并使用它。请注意,并非数据集中的每个列都必须在dbgrid中可见。此外,数据集中可能存在计算字段,因此请不要忘记这些字段。创建映射的最安全方法是迭代dbgrid的列,并将其字段名称与列索引一起存储。这样您就不会获得任何无效条目,并且映射中没有的任何字段都没有dbgrid列。
答案 2 :(得分:0)
我想做类似的事情,但我在想,如果 dbgrid 不知道列名 (对于这种情况),也许还有其他 (说到组件) 确实已经知道了。
就我而言,我使用 fdquery -> 数据源 -> DBgrid 连接。 FDQuery 通过名称和 ID 识别字段。
因此考虑到您使用类似的组件,您可以做到
dbgrid1.Columns[fdquery1.FieldByName('UnitPrice').Index].visible:=false;