Delphi 数据库网格 Expand/Collapse

Delphi DBgrid Expand/Collapse

我正在尝试在 Delphi DBGrid 中实现 expand/collapse 选项。 遗憾的是,它不是默认支持的选项。用于显示的数据来自 ADOStoredProcedure.

必须为 DBGrid 创建该功能,使用替代组件库不是一个选项。 SMDBGrid 可用(也不支持 e/c)

搜索 Google 还没有给我任何有用的信息。我想知道这里是否有人解决了这个问题或知道如何解决这个问题。

提前致谢!

花了一些时间,但我设法使用数据集上的动态过滤器为 DBGrid 创建了功能。我会 post 为需要此功能的人提供代码。

Class 存储扩展项

type
  //Store ID's used to keep expanded items
  TPlanningFilterItem = class(TObject)
    public
      Sublevel, ProjectID, OnderdeelID, MedewerkerID: integer;
  end;

捕获指示器点击

  procedure TFPlanningOverzicht.GridPlanningDblClick(Sender: TObject);
  var
    P: TPoint;
    C: TGridCoord;
  begin
    GetCursorPos(P);
    P := (Sender as TCustomGrid).ScreenToClient(P);
    C := (Sender as TCustomGrid).MouseCoord(P.X, P.Y);

    //Only capture indicator row X = 0
    //Ignore title indicator Y > 1
    if (C.X = 0) AND (C.Y > 0) then
      DatasetFilterToevoegenVerwijderen;
      FilterDataSet;
    begin
    end;
  end;

添加或删除过滤器

  procedure TFPlanningOverzicht.DatasetFilterToevoegenVerwijderen;
  var
    newFilterItem: TPlanningFilterItem;
    tmp: TPlanningFilterItem;
    I: Integer;
  begin
      newFilterItem := TPlanningFilterItem.Create;
      newFilterItem.Sublevel := DPlanning.PlanningOverzicht.FieldByName('SUBLEVEL').AsInteger;
      newFilterItem.ProjectID := DPlanning.PlanningOverzicht.FieldByName('ProjectID').AsInteger;
      newFilterItem.OnderdeelID := DPlanning.PlanningOverzicht.FieldByName('OnderdeelID').AsInteger;
      newFilterItem.MedewerkerID := DPlanning.PlanningOverzicht.FieldByName('MedewerkerID').AsInteger;

      //Ignore expand when deepest lvl reached
      if newFilterItem.Sublevel > 2 then
        Exit;

      for I := 0 to GridFilterItems.Count - 1 do
      begin
        //Compare to existing
        tmp := GridFilterItems.Items[I];
        if (tmp.Sublevel = newFilterItem.Sublevel) AND
            (tmp.ProjectID = newFilterItem.ProjectID) AND
            (tmp.OnderdeelID = newFilterItem.OnderdeelID) AND
            (tmp.MedewerkerID = newFilterItem.MedewerkerID)
        then
        begin
          //If item currently expanded collapse and exit
          GridFilterItems.Delete(I);
          Exit;
        end;
      end;

      //Item not yet expanded, so expand
      GridFilterItems.Add(newFilterItem);
  end;

正在应用过滤器

  procedure TFPlanningOverzicht.FilterDataSet;
  var
    I: integer;
    tmp: TPlanningFilterItem;
    Filter: string;
    C: Integer;
  begin
    //Always show top level items
    Filter := '(SUBLEVEL = ''' + IntToStr(1) + ''' ) OR ';

    for I := 0 to GridFilterItems.Count - 1 do
    begin
      tmp := GridFilterItems[I];

      //Expand when 1st row selected (shoud be written to your case)
      if (tmp.Sublevel= 1) then
      begin
        Filter := Filter +
        '(MedewerkerID = ''' + IntToStr(tmp.MedewerkerID) + ''' AND ' +
        'SUBLEVEL = ''' + IntToStr(2) + ''' ) OR ';
      end
      else
      begin
        //Expands for the second level (shoud be written to your case)
        Filter := Filter +
        '(MedewerkerID = ''' + IntToStr(tmp.MedewerkerID) + ''' AND ' +
        'OnderdeelID = ''' + IntToStr(tmp.OnderdeelID) + ''' AND ' +
        'SUBLEVEL = ''' + IntToStr(3) + ''' ) OR ';
      end;
    end;

    //Remove last or
    Delete(Filter, Filter.Length - 2, 3);

    GridPlanning.DataSource.DataSet.Filter := Filter;
    GridPlanning.DataSource.DataSet.Filtered := True;
  end;

希望这对某人有用。