Get Column Object for DataSet Field

2019-08-10 09:34发布

问题:

Let's say, I have a set of TField objects and want to change their visibility in some DBGrid dynamically. I also want to allow users to change column order in this DBGrid, and have some fixed columns.

I know proper way to hide/show columns on DBGrid, but there is a big, big design flaw in VCL: having Column object, one can travel to it's Field object, but cannot find way back.

All I want is just kind of Column property inside Field object, so I can type something like this:

Field.Column.Visible := False;

and hide any column inside DBGrid with assigned Columns property.

I know I can just create HashSet or Collection with Columns and quickly find corresponding columns, but is there exist more straight way to do this?

回答1:

If column are stored, may use something like:

function FindFieldColumn(Grid : TDBGrid; const FieldName: String):  TColumn;
var
  i: Integer;
begin
  Result := nil;
  for i := 0 to Grid.Columns.Count - 1 do
    if AnsiCompareText(Grid.Columns[i].FieldName, FieldName) = 0 then
      begin
         Result := Grid.Columns[i];
         Break;
      end;
end;

procedure SetVisibleColumn(Grid : TDBGrid; AFieldName : string; AVisible : boolean);
var
  Column : TColumn;
begin
  Column := FindFieldColumn(Grid,AFieldName);
  if Assigned(Column) then
     Column.Visible := AVisible;
end; 

Call

SetVisibleColumn(MyGrid,MyField.Name, myField.Visible);


回答2:

@UweRaabe has already explained that what you're asking is not in general possible, basically because DGGrids know which fields they're connected to but not vice versa. So to do what you want, you're going to have to code it yourself, if you're using persistent columns in your grid.

I don't know whether you're aware, but for the benefit of other readers, a TField has Visible and Index properties.

A Field's Visible property can be used by DBGrids to control whether the field's Column in the DBGrid is visible, but only when the Columns are auto-created by setting the grid's DefaultFields to true.

Likewise, a Field's Index defines its column number in DBGrids, but again only when the DBGrid's DefaultFields is True.

In a DBGrid wih DefaultFields = True, you can change the visibility an column number of a Field at run-time.

So, although you can't centrally control the visibility and number of a column in a DBGrid which has persistent Columns, you can if you set DefaultFields to True and leave it to the grid(s) to create the columns.