Delphi 每次TDbGrid';您选择的位置是否已更改?

Delphi 每次TDbGrid';您选择的位置是否已更改?,delphi,datagrid,event-handling,Delphi,Datagrid,Event Handling,我的项目中有一个TDbGrid,每次更改所选行时,我都会尝试启动一个事件。行中的任何更改都已经更新了链接到同一数据源的所有数据感知控件,但还有其他更改需要进行,我需要一个事件处理程序 我以为Onclenter会管用的。根据帮助文件,它在以下情况下激发: 用户使用 键盘。例如,当 用户使用Tab键或Home键 钥匙 用户单击鼠标按钮 在牢房里 SelectedField或SelectedIndex 属性已设置 不幸的是,当用户在启用dgRowSelect选项且没有OnRowEnter时使用键盘

我的项目中有一个TDbGrid,每次更改所选行时,我都会尝试启动一个事件。行中的任何更改都已经更新了链接到同一数据源的所有数据感知控件,但还有其他更改需要进行,我需要一个事件处理程序

我以为Onclenter会管用的。根据帮助文件,它在以下情况下激发:

  • 用户使用 键盘。例如,当 用户使用Tab键或Home键 钥匙

  • 用户单击鼠标按钮 在牢房里

  • SelectedField或SelectedIndex 属性已设置


不幸的是,当用户在启用dgRowSelect选项且没有OnRowEnter时使用键盘导航时,它不会触发。并且OnKeyDown事件在选择更改之前激发。我试图在这里模拟一个TListBox的数据感知版本,我需要一些东西来替换列表框的OnClick处理程序,不管名称是什么,只要选择被更改,不管是通过鼠标还是键盘,它实际上都会熄灭。有什么办法可以用TDbGrid实现吗?如果不是的话,一定会有其他的网格控件来完成。有人知道这是什么吗?(最好是开源?

是否尝试过数据源的OnDataChange事件?

使用OnDataChange并处理加载数据集的情况,添加布尔检查作为例程的第一行,并在加载完成时将其设置为false

procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
begin
  if fbLoading then exit;
  // rest of your code here
end;

procedure TForm1.Form1Create(Sender:tObject);
begin
  fbLoading := true;
  // load your table here     
  fbLoading := false; 
end;

OnDataChange是一种选择。另一个是在TDataset端,事件余波。大多数时候,我发现它比OnDataChange更实用;因为在OnDataChange中,scroll事件带有字段参数nil(这是一个陷阱,可能是AVs对其进行编码的原因之一)。

我只会在数据集上使用AfterScroll,它会在您首次打开数据集时触发,每次移动数据集时触发。在DBGrid中,每次单击一行、滚动条或使用键盘(Home、Edn、Up、Down、PgUp、PgDown)时都会出现这种情况

如果以多种不同的形式使用同一数据集(创建/免费或显示/关闭),甚至可以动态分配该数据集:

过程TForm1.myAfterScroll(数据集:TDataSet);
开始
//在这里做你的事
如果没有,那么
oldAfterScroll(数据集);
结束;
构造函数TForm1.Create(所有者:TComponent);
开始
oldAfterScroll:=DBGrid1.DataSet.OnAfterScroll;
DBGrid1.DataSet.OnAfterScroll:=MyAddressCroll;
结束;
析构函数TForm1.Free;
开始
DBGrid1.DataSet.OnAfterScroll:=oldAfterScroll;
结束;

如果尼克这么说,我想我不得不接受。我必须做一些额外的工作,以防止每次对数据集进行任何更改时触发这个愚蠢的东西,例如,当我还在填充数据集时,处理程序中的代码会导致AVs。我希望有更好的解决方案。是的,我想我更喜欢这个。但是
SelCount
SelectedRows
TDBGrid
属性在
OnDataChange
aftercroll
事件上都没有改变。如何访问实际选定的行数据?@Altaveron:TDbGrid更改关联数据源的实际行指针,因此如果执行
Grid.datasource.Dataset.FieldByName([字段名称])
操作,您将从当前记录中获取数据。如果我的内存没有问题,则只有在您将网格配置为允许选择多行时,才能使用selcount和selectedRows。@Fabricio我想让用户选择多行,但在任何情况下,只有上一个选择是可访问的。您是否尝试了CrollData?它应该有用!
procedure TForm1.myAfterScroll(DataSet: TDataSet); 
begin
   //do your thing here
   if oldAfterScroll<>nil then
      oldAfterScroll(DataSet);
end;

constructor TForm1.Create(AOwner: TComponent);
begin
   oldAfterScroll:=DBGrid1.DataSet.OnAfterScroll;
   DBGrid1.DataSet.OnAfterScroll:=myAdrerScroll;
end;

destructor TForm1.Free;
begin
   DBGrid1.DataSet.OnAfterScroll:=oldAfterScroll;
end;