【问题标题】:Setting TDBGrid visible rows设置 TDBGrid 可见行
【发布时间】:2017-11-15 09:08:55
【问题描述】:

我想在给定VisibleRows 参数的情况下调整 TDBGrid 高度。网格可能有也可能没有标题。

假设我从数据库中选择了 100 条记录,但我希望调整网格高度以显示前 10 行(使它们可见)。数据集仍将包含 100 条记录。

procedure SetVisibleRows(DBGrid: TCustomDBGrid; VisibleRows: Integer);
begin
  ...
  DBGrid.Height := ???
end;

我知道如何获取可见行:

type
  TCustomGridHack = class(TCustomGrid);

function GetVisibleRows(DBGrid: TCustomDBGrid): Integer;
begin
   Result := TCustomGridHack(DBGrid).VisibleRowCount;
end;

但是,有没有办法设置VisibleRowCount

【问题讨论】:

  • @nil,谢谢。我知道这是一个只读属性。我实际上是从 “增加或减少高度直到 VisibleRowCount 和 DesiredVisibleRows 相同”开始的” - 但我不喜欢它。请参阅我的答案以获得可能的解决方案。
  • 我明白,尝试感觉不太好。我当时尝试的与您的类似,但基于网格创建的绘制信息。
  • @nil,我确实看到了GetVisibleRowCount 方法,但是网格客户端高度是否可以由TGridDrawInfo设置?我只找到了它的计算。如果您有工作代码,请随时分享:)
  • 没有什么比你的代码更重要的了。除了使滚动条表现得时髦之外。正在考虑这样的事情:
  • 过程 SetVisibleRows(DBGrid: TCustomDBGrid; VisibleRows: Integer); var AGridDrawInfo: TGridDrawInfo; AClientHeight:整数;一:整数;开始 TDBGridAccess(DBGrid).CalcDrawInfo(AGridDrawInfo); AClientHeight := AGridDrawInfo.Vert.FixedBoundary;对于 I := AGridDrawInfo.Vert.FirstGridCell 到 VisibleRows do Inc(AClientHeight, (AGridDrawInfo.Vert.GetExtent(I) + AGridDrawInfo.Vert.EffectiveLineWidth)); DBGrid.ClientHeight := AClientHeight;结束;

标签: delphi tdbgrid


【解决方案1】:

这似乎可行(也许可以进一步优化):

type
  TCustomDBGridHack = class(TCustomDBGrid);

procedure SetVisibleRows(DBGrid: TCustomDBGrid; VisibleRows: Integer);
var
  TitleHeight, RowHeight: Integer;
begin
  with TCustomDBGridHack(DBGrid) do
  begin
    if dgTitles in Options then
    begin
      TitleHeight := RowHeights[0] + GridLineWidth;
      RowHeight := RowHeights[1] + GridLineWidth;
    end
    else
    begin
      TitleHeight := 0;
      RowHeight := RowHeights[0] + GridLineWidth;
    end;
  end;
  DBGrid.ClientHeight := TitleHeight + (RowHeight * VisibleRows) + 1;
end;

或者按照@nil 的建议使用TGridDrawInfo。它会产生更准确的结果(我对其进行了一些修改):

procedure SetVisibleRows(DBGrid: TCustomDBGrid; VisibleRows: Integer);
var
  DrawInfo: TGridDrawInfo;
  TitleHeight, RowHeight: Integer;
begin
  with TCustomDBGridHack(DBGrid) do
  begin
    CalcDrawInfo(DrawInfo);
    TitleHeight := DrawInfo.Vert.FixedBoundary;
    RowHeight := RowHeights[DrawInfo.Vert.FirstGridCell] + DrawInfo.Vert.EffectiveLineWidth;
  end;
  DBGrid.ClientHeight := TitleHeight + (RowHeight * VisibleRows) + 1;
end;

正如@nil 所述,RowHeight 也可以通过以下方式计算:

RowHeight := DrawInfo.Vert.GetExtent(DrawInfo.Vert.FirstGridCell) + DrawInfo.Vert.EffectiveLineWidth; 

虽然我没有注意到任何不同。 (应进一步调查)。

以上内容可以进一步改进以使TDBGrid滚动条调整得更好:

procedure SetVisibleRows(DBGrid: TCustomDBGrid; VisibleRows: Integer);
var
  DrawInfo: TGridDrawInfo;
  TitleHeight, RowHeight: Integer;
  HasActiveDataSet: Boolean;
begin
  if VisibleRows < 0 then VisibleRows := 0;
  HasActiveDataSet := Assigned(DBGrid.DataSource) and
    Assigned(DBGrid.DataSource.DataSet) and
    DBGrid.DataSource.DataSet.Active;
  if HasActiveDataSet then
    DBGrid.DataSource.DataSet.DisableControls;
  try
    with TCustomDBGridHack(DBGrid) do
    begin
      CalcDrawInfo(DrawInfo);
      TitleHeight :=  DrawInfo.Vert.FixedBoundary;
      RowHeight := RowHeights[DrawInfo.Vert.FirstGridCell] + DrawInfo.Vert.EffectiveLineWidth;      
    end;
    DBGrid.ClientHeight := TitleHeight + (RowHeight * VisibleRows) + 1;
  finally
    if HasActiveDataSet then
      DBGrid.DataSource.DataSet.EnableControls;
  end;
end;

【讨论】:

  • 我也建议使用DrawInfo 而不是RowHeights 进行小修改。我不能说任何方法更好。在某些情况下,两者都需要考虑行的不同高度 - 据我了解,这是可能的。这就是为什么我认为循环行可能是必要的。我使用TSpinEdit 动态更改VisibleRows 并注意到垂直滚动条更新是lazy。仅在高度更改后选择一行后更新。
  • @nil,谢谢。我进行了编辑并提到了另一个选项。不过我没有注意到任何区别。 AFAIK TDBgrid 不能有可变的行高。所以我认为依靠第一个数据行是安全的。我现在才注意到时髦的垂直滚动条行为。它可以通过使用网格DataSource.DatSet.DisableControls/EnableControls 来“修复”(如果它附加了DataSet)。
  • 感谢您的编辑,我的编辑被拒绝了。滚动条的一个很好的“修复”,我无法落后。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-02
  • 2015-12-17
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
相关资源
最近更新 更多