Delphi DBgrid展开/折叠

时间:2015-04-02 08:27:47

标签: delphi stored-procedures adodb dbgrid

我试图在Delphi DBGrid 中实现展开/折叠选项。 遗憾的是,它不是默认支持的选项。用于显示的数据来自 ADOStoredProcedure

必须为DBGrid创建函数,使用替代组件lib 不是选项。虽然SMDBGrid是可用的(也不支持e / c)

搜索Google并没有给我任何有用的信息。我想知道这里是否有人解决过这个问题,或者想知道怎么做。

提前致谢!

1 个答案:

答案 0 :(得分:1)

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

用于存储展开项目的类

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;

希望这对某人有用。