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;
希望这对某人有用。
我正在尝试在 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;
希望这对某人有用。