使用 SelectedRows.Count 我可以获得所选网格行数的计数。例如,如果用户选择了 3 行,我可以在表单上放置一个按钮并单击它可以显示所选的数字。美好的。

但是如何在用户选择行数时更新行数(“即时”)。我尝试了许多 Grid 事件,例如 OnColEnterOnMouseDown 。它们似乎仅在用户单击数据列之外时才更新计数,而不是在第一次选择行时。

Grid 组件中没有看到与更改 ROWS 相关的事件,我在底层数据查询中尝试了许多事件,但它们也不一致或经常需要在某些地方单击。我发现的最佳结果(实际代码)是在滚动查询之后:

procedure TDataHerd10.QuCowsAfterScroll(DataSet: TDataSet);
begin
  if MenuOpt = 'UpdtInd' then MainView.NumSelEdit.Text:=
    IntToStr(MainView.CowSelGrid.SelectedRows.Count);
end;

这个事件似乎落后了一个,当用户放弃多选返回到单行时,最初会在计数上增加一个。

似乎对于正确的事件,我应该能够计算所选行以在用户选择/取消选择行时向用户报告?

最佳答案

更新: 我发现修改原始文件比我预期的要棘手
回答以可靠地满足您显示选择计数的要求
当表单第一次显示时。

以下是测试平台项目的基本要素,我希望它们能够可靠地运行
正如你所要求的。除了 DBGrid 之外,表单还有一个 TEdit,我使用它
确保 dbgrid 最初没有被聚焦(以便更容易观察 dbgrid 的行为)和 3 个 TButtons
函数应该从它们的 OnClick 处理程序中不言而喻。

您会注意到,捕获更改计数的代码
dbgrid 的选择计数仅在 dbgrid 的 OnDrawColumnCell 中触发
事件。但是,这被称为过于频繁(在我的情况下超过 700
表单第一次显示之前的时间)做其他事情
每次触发时都在 gui 中。所以相反,表单有一个变量
它跟踪选择计数并只更新它的显示
当计数改变时(在 SetSelectedCount setter 中)。

type
  TForm1 = class(TForm)
    [...]
  private
    FSelectedCount: Integer;
    procedure SetSelectedCount(const Value: Integer);
  public
    procedure ShowSelectedCount;
    property SelectedCount : Integer read FSelectedCount write SetSelectedCount;
  end;
 [...]

procedure TForm1.btnClearSelectedClick(Sender: TObject);
begin
  DBGrid1.SelectedRows.Clear;
end;

procedure TForm1.btnGetSelectedClick(Sender: TObject);
begin
  ShowSelectedCount;
end;

procedure TForm1.btnSetSelectedClick(Sender: TObject);
begin
  DBGrid1.SelectedRows.CurrentRowSelected := True;
end;

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
    DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
  SelectedCount := DBGrid1.SelectedRows.Count;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ActiveControl := Edit1;  // so the grid does not have focus when the form is first shown
  SelectedCount := -1;
end;

procedure TForm1.SetSelectedCount(const Value: Integer);
begin
  if FSelectedCount <> Value then begin
    FSelectedCount := Value;
    ShowSelectedCount;
  end;
end;

procedure TForm1.ShowSelectedCount;
begin
  Caption := IntToStr(DBGrid1.SelectedRows.Count);
end;

原答案如下

我通常使用 DataSet.AfterScroll 来做需要与其当前行同步的非 gui 事情。不幸的是,它不适用于 DBGrid,正如您显然已经发现的那样,尤其是因为可以更改网格中当前行的选择状态(例如,通过单击它)而无需滚动数据集。

很遗憾,
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
  Caption := IntToStr(DBGrid1.SelectedRows.Count);
end;

也不能很好地完成这项工作,原因很明显,您可以在不使用鼠标的情况下从当前行扩展选择 - 例如Shift + Down 也可以。

但是,如果您只是添加
procedure TForm1.DBGrid1KeyUp(Sender: TObject; var Key: Word; Shift:
    TShiftState);
begin
  Caption := IntToStr(DBGrid1.SelectedRows.Count);
end;

考虑到使用键盘来更改选择,并且到目前为止已经抵制了我错误的尝试。如果您允许用户在网格中进行就地编辑,您可能需要过滤用于更新选择计数显示的 Key 值。

顺便说一句,考虑到键盘的皱纹以及 AfterScroll 的问题,你的 q 似乎不值得(无论如何对我来说)它得到的反对票,所以我给了它+1。

关于Delphi 网格 : How to get selectedrows count "on the fly",我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41905563/

10-10 19:55