DBGrid 和 DBGridEh 的列可见性的通用处理程序

Common handler for DBGrid and DBGridEh's columns visibility

TDBGridEh属于哪个class?我试过了:

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 
 

但我收到错误:未声明的标识符“***”

更新:

这是我对 TMainMenu 的子元素和 TDBGrid 的列的常用处理程序。我必须在这个通用处理程序中添加一些 TDBGridEh.

的代码

有没有办法为 TDBGridTDBGridEhTMainMenu 的子元素设置一个过程?

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;

What is parent class of DBGridEh component?

根据 EhLib 的 documentation:

所以,当 AForm.Components[i] 引用一个 TDBGridEh 对象时,它将对 TDBGridEh 测试为阳性,但对 TCustomDBGridTCustomGrid 测试为阴性, 和 TDBGrid.

您已经知道如何区分 TMainMenuTDBGrid,那么是什么阻止您区分 TDBGridEhTDBGrid

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;

也就是说,由于 TDBGridEh 具有与 TDBGrid 相似的接口,但实际上并非派生自 TDBGrid,因此在 Delphi 2009+ 中,您可以为两者编写通用代码 TDBGridTDBGridEh 通过使用 Generics,例如:

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;