4

I've got a TDbGrid in my project, and I'm trying to have an event go off every time I change the selected row. Any change in row already updates all the data-aware controls linked to the same DataSource, but there are other changes to be made too, that I need an event handler for.

I thought OnColEnter would work. According to the helpfile, it fires when:

  • The user navigates to the cell using the keyboard. For example, when the user uses the Tab key, or the Home key.

  • The user clicks the mouse button down in the cell.

  • The SelectedField or SelectedIndex property is set.

Unfortunately, it does not fire when the user navigates using the keyboard while the dgRowSelect option is enabled, and there's no OnRowEnter. And the OnKeyDown event fires before the selection change has been made. I'm trying to simulate a data-aware version of a TListBox here, and I need something to replace the List Box's OnClick handler, which despite the name actually goes off anytime the selection is changed, whether through the mouse or the keyboard. Is there any way I can do that with a TDbGrid? If not, there's got to be some other grid control that will do it. Does anyone know what it is? (Preferably open source?)

Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477

4 Answers4

8

Have you tried OnDataChange event of DataSource?

Lars Truijens
  • 42,837
  • 6
  • 126
  • 143
  • Well, if Nick said so, I guess I'll have to accept it. I had to do some extra work to keep the stupid thing from firing every time any change was made to the dataset, such as while I'm still populating it, during which time the code in the handler causes AVs. I wish there was a better solution. – Mason Wheeler Nov 17 '08 at 14:41
3

OnDataChange is one choice. The other is, on TDataset side, the event AfterScroll. Most times, I found it more practical than OnDataChange; because in OnDataChange a scroll event comes with the Field parameter nil (which is a trap and can be one of the cause of your AVs coding it).

Fabricio Araujo
  • 3,810
  • 3
  • 28
  • 43
  • Yeah, I think I like that one better. – Mason Wheeler Nov 19 '08 at 00:21
  • But `SelCount` and `SelectedRows` properties of `TDBGrid` are not changed on both `OnDataChange` and `AfterScroll` events. How can I access the actual selected rows data? – Dmitry Dec 05 '14 at 00:15
  • @Altaveron: TDbGrid alters the actual row pointer of the datasource associated, so if do `Grid.Datasource.Dataset.FieldByName([name of the field])` you'll get the data from the current record. If my memory does not fail me, selcount and selectedRows are only for use when you config the grid to allow the selection of multiple rows. – Fabricio Araujo Dec 05 '14 at 21:23
  • @Fabricio I want to get multiple rows selected by user but on any event only the previous selection is accessible. – Dmitry Dec 06 '14 at 16:35
2

Use the OnDataChange and to handle the case where your loading the dataset, add a boolean check as the first line of the routine, and set this to false when your loading is complete.

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;
skamradt
  • 15,366
  • 2
  • 36
  • 53
1

I would only use AfterScroll on the dataset, it is fired when you first open the dataset, and every time you move in it. In a DBGrid, that would be on every click on a row, or the scrollbar, or using the keyboard (Home, Edn, Up, Down, PgUp,PgDown) ...etc.

You could even dynamically assign it if you use the same Dataset in many different forms (Either in Create/Free or Show/Close):

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;
Osama Al-Maadeed
  • 5,654
  • 5
  • 28
  • 48