Home > Software engineering >  Common handler for DBGrid and DBGridEh's columns visibility
Common handler for DBGrid and DBGridEh's columns visibility

Time:12-05

Which class does TDBGridEh belong to? I tried:

if (AForm.Components[i] IS TDBGridEh)
if (AForm.Components[i] IS TCustomDBGrid) or 
if (AForm.Components[i] IS TCustomGrid) or
if (AForm.Components[i] IS TDBGrid) or 
 

but I get error: undeclared identifier '***'

UPDATE:

This is my common handler for subelements of TMainMenu, and for columns of TDBGrid. I have to add in this common handler some code for TDBGridEh.

Is there a way to have one procedure for subelements of TDBGrid, TDBGridEh, and TMainMenu?

procedure RightsOnSubElements(AForm: TForm; AComp: TComponent);

  function FindFieldColumn(AComp: TComponent; const FieldName: String):  TColumn;
  var
    i: Integer;
  begin
    Result := nil;
    for i := 0 to (AComp as TDBGrid).Columns.Count - 1 do
      if AnsiCompareText((AComp as TDBGrid).Columns[i].FieldName, FieldName) = 0 then
      begin
        Result := (AComp as TDBGrid).Columns[i];
        Break;
      end;
  end;
     
var
  Column : TColumn;
  i: Integer;
begin
  fMain.qSubElements.Close;
  fMain.qSubElements.Parambyname('Form_Name').AsString := AForm.Name;
  fMain.qSubElements.Parambyname('ROLE_ID').AsInteger := ROLE_ID;
  fMain.qSubElements.Parambyname('name').AsString := AComp.Name;
  fMain.qSubElements.Open;
  if fMain.qSubElements.RecordCount > 0 then begin
    while not fMain.qSubElements.Eof do begin
      for i := 0 to AForm.ComponentCount - 1 do
        if (AForm.Components[i] is TMenuItem) then begin
          if UpperCase(AForm.Components[i].Name) = UpperCase(fMain.qSubElements.FieldByName('Sub_Name').AsString) then
          begin
            (AForm.Components[i] as TMenuItem).Visible := fmain.qSubElements.FieldByName('Visible').AsBoolean;
            (AForm.Components[i] as TMenuItem).Enabled := fmain.qSubElements.FieldByName('Enabled').AsBoolean;
          end;
        end
        else if (AForm.Components[i] is TDBGrid) then begin
          if UpperCase(AForm.Components[i].Name) = UpperCase(fMain.qSubElements.FieldByName('Name').AsString) then
          begin
            Column := FindFieldColumn(AComp as TDBGrid, fMain.qSubElements.FieldByName('sub_name').AsString);
            if Assigned(Column) then Column.Visible := fMain.qSubElements.FieldByName('Visible').AsBoolean;
          end;
      end;
                
      fMain.qSubElements.Next;
    end;
  end;
end;

CodePudding user response:

What is parent class of DBGridEh component?

According to EhLib's documentation:

So, when AForm.Components[i] refers to a TDBGridEh object, it will test positive for TDBGridEh, but will test negative for TCustomDBGrid, TCustomGrid, and TDBGrid.

You already know how to differentiate TMainMenu from TDBGrid, so what is stopping you from differentiating TDBGridEh from TDBGrid?

procedure RightsOnSubElements(AForm: TForm; AComp: TComponent);

  function FindFieldColumn(AComp: TDBGrid; const FieldName: String): TColumn;
  var
    i: Integer;
  begin
    for i := 0 to AComp.Columns.Count - 1 do begin
      Result := AComp.Columns[i];
      if SameText(Reslut.FieldName, FieldName) then
        Exit;
    end;
    Result := nil;
  end;
     
  function FindFieldColumnEh(AComp: TDBGridEh; const FieldName: String): TColumnEh;
  var
    i: Integer;
  begin
    for i := 0 to AComp.Columns.Count - 1 do begin
      Result := AComp.Columns[i];
      if SameText(Result.FieldName, FieldName) then
        Exit;
    end;
    Result := nil;
  end;

var
  Comp: TComponent;
  Column : TColumn;
  ColumnEh : TColumnEh;
  i: Integer;
begin
  fMain.qSubElements.Close;
  fMain.qSubElements.Parambyname('Form_Name').AsString := AForm.Name;
  fMain.qSubElements.Parambyname('ROLE_ID').AsInteger := ROLE_ID;
  fMain.qSubElements.Parambyname('name').AsString := AComp.Name;
  fMain.qSubElements.Open;
  while not fMain.qSubElements.Eof do begin
    Comp := AForm.FindComponent(fMain.qSubElements.FieldByName('Name').AsString);
    if (Comp is TMenuItem) then begin
      with TMenuItem(Comp) do begin
        Visible := fmain.qSubElements.FieldByName('Visible').AsBoolean;
        Enabled := fmain.qSubElements.FieldByName('Enabled').AsBoolean;
      end;
    end
    else if (Comp is TDBGrid) then begin
      Column := FindFieldColumn(TDBGrid(Comp), fMain.qSubElements.FieldByName('Sub_Name').AsString);
      if Column <> nil then Column.Visible := fMain.qSubElements.FieldByName('Visible').AsBoolean;
    end
    else if (Comp is TDBGridEh) then begin
      ColumnEh := FindFieldColumnEh(TDBGridEh(Comp), fMain.qSubElements.FieldByName('Sub_Name').AsString);
      if Column <> nil then Column.Visible := fMain.qSubElements.FieldByName('Visible').AsBoolean;
    end;                
    fMain.qSubElements.Next;
  end;
end;

That being said, since TDBGridEh has similar interfaces to, but is not actually derived from, TDBGrid, then in Delphi 2009 you could write common code for both TDBGrid and TDBGridEh by using Generics, eg:

type
  TInternalDBGridHelper<TDBGridType: class, TColumnType: class> = class 
    class function FindFieldColumn(AGrid: TDBGridType; const AFieldName: string): TColumnType;
    class procedure SetFieldColumnVisible(AGrid: TDBGridType; const AFieldName: string; AVisible: Boolean);
  end;

  TInternalHelper_DBGrid   = TInternalDBGridHelper<TDBGrid, TColumn>;
  TInternalHelper_DBGridEh = TInternalDBGridHelper<TDBGridEh, TColumnEh>;

  TDBGridHelper = class helper for TDBGrid
    procedure SetFieldColumnVisible(const AFieldName: string; AVisible: Boolean);
  end;

  TDBGridEhHelper = class helper for TDBGridEh
    procedure SetFieldColumnVisible(const AFieldName: string; AVisible: Boolean);
  end;

class function TInternalDBGridHelper<TDBGridType, TColumnType>.FindFieldColumn(
  AGrid: TDBGridType; const AFieldName: string): TColumnType;
var
  I: Integer;
begin
  for I := 0 to AGrid.Columns.Count-1 do
  begin
    Result := AGrid.Columns[I];
    if SameText(Result.FieldName, AFieldName) then
      Exit;
  end;
  Result := nil;
end;

class function TInternalDBGridHelper<TDBGridType, TColumnType>.SetFieldColumnVisible(
  AGrid: TDBGridType; const AFieldName: string; AVisible: Boolean);
var
  Column: TColumnType;
begin
  Column := FindFieldColumn(AGrid, AFieldName);
  if Assigned(Column) then Column.Visible := AVisible;
end;

procedure TDBGridHelper.SetFieldColumnVisible(const AFieldName: string; AVisible: Boolean);
begin
  TInternalHelper_DBGrid.SetFieldColumnVisible(Self, AFieldName, AVisible);
end;

procedure TDBGridEhHelper.SetFieldColumnVisible(const AFieldName: string; AVisible: Boolean);
begin
  TInternalHelper_DBGridEh.SetFieldColumnVisible(Self, AFieldName, AVisible);
end;

procedure RightsOnSubElements(AForm: TForm; AComp: TComponent);
var
  Comp: TComponent;
  i: Integer;
begin
  fMain.qSubElements.Close;
  fMain.qSubElements.Parambyname('Form_Name').AsString := AForm.Name;
  fMain.qSubElements.Parambyname('ROLE_ID').AsInteger := ROLE_ID;
  fMain.qSubElements.Parambyname('name').AsString := AComp.Name;
  fMain.qSubElements.Open;
  while not fMain.qSubElements.Eof do begin
    Comp := AForm.FindComponent(fMain.qSubElements.FieldByName('Name').AsString);
    if (Comp is TMenuItem) then begin
      with TMenuItem(Comp) do begin
        Visible := fmain.qSubElements.FieldByName('Visible').AsBoolean;
        Enabled := fmain.qSubElements.FieldByName('Enabled').AsBoolean;
      end;
    end
    else if (Comp is TDBGrid) then begin
      TDBGrid(Comp).SetFieldColumnVisible(
        fMain.qSubElements.FieldByName('Sub_Name').AsString,
        fMain.qSubElements.FieldByName('Visible').AsBoolean);
    end
    else if (Comp is TDBGridEh) then begin
      TDBGridEh(Comp).SetFieldColumnVisible(
        fMain.qSubElements.FieldByName('Sub_Name').AsString,
        fMain.qSubElements.FieldByName('Visible').AsBoolean);
    end;                
    fMain.qSubElements.Next;
  end;
end;
  • Related