Unfortunately, the DBGrid behaviour you are describing is not a bug, it is deliberate :-(
I have seen the DBGrid behaviour you are talking about in a particular 16 bit program running under Windows 3.1 - then Win XP for far too long, which makes me believe the functionality dates back at least to Delphi 1. The RecordCount issue we discuss over in the other topic also date back to that era. Both of these are deliberate design decisions, rather than Bugs per se. Doesn't mean I like them.
I absolutely cring everytime I see a commercial app implement the default TDBGrid for exactly the reasons you have described. With a little modification, you can easily implement what I consider to the minimum working DB Aware Grid. It involves disabling the DBGrid Vert Scrollbar, and implementing your own. I'll dig around in a tick and post an example of this.
Big problem for me, is that this workaround will rely on RecordCount being correct. Good news for you, you're in ZEOSLib world. RecordCount will be correct for you, so you can implement this workaround.
As you've worked out TKDBGrid was written from the ground up. I have a LOT of respect for TKDBGrid, and the whole KControl Suite, but unfortunately the author has stopped development on TKDBGrid. I originally tried to base my code around TSQLQuery and TKDBGrid. Some minor UI issues in TKDBGrid (relating to horizontal scrolling IIRC) meant I moved away that pair. The whole RecordCount issue meant I ended up with ZEOSLib/DBGrid c/w Scrollbar workaround for most of my stuff, but for MS SQL, I'm stuck with TSQLQuery/TDBGrid with no workaround.
The following code requires a Scrollbar called sbScroll aligned vertically to the right of a DBGrid called grdSQL. In the ObjectInspector, set grdSQL.ScrollBars to ssAutoHorizontal. In my code, I've got the above arrangement sitting in a Frame I call TFrameGrid. I then use this Frame where-ever I need a working DBGrid. This Frame has a Dataset property, which reads or sets FDataset : TDataset. The frame has it's own DataSource, called dsGrid.
Sorry for only posting partial code, there is also Filtering code in this Frame, which is frankly awful. @BigChimp pointed me towards some TDBF documentation which contains everything I need to get that working. Another reason for not posting full code is my TFrameGrid is inherited from some more Frames, so I would really need to post the whole framework...
// There's a few places I call this in code... Can't remember my logic as TDataSource.OnStateChange should cover all...
Procedure TFrameGrid.UpdateScrollbar;
Begin
If (FDataset.Active) And (FDataset.RecordCount > 0) Then
Begin
sbScroll.Enabled := True;
sbScroll.SetParams(FDataset.RecNo, 1, FDataset.RecordCount);
End
Else
Begin
sbScroll.Enabled := False;
sbScroll.SetParams(1, 1, 100);
End;
End;
// Hook the sbScroll.OnScroll to this event...
Procedure TFrameGrid.sbScrollScroll(Sender: TObject; ScrollCode: TScrollCode;
Var ScrollPos: Integer);
Begin
If FDataset.Active Then
FDataset.RecNo := ScrollPos
End;
// Hook your TDataSource.OnDataChange to this event...
Procedure TFrameGrid.dsGridDataChange(Sender: TObject; Field: TField);
Begin
If (Not FDataset.ControlsDisabled) And (sbScroll.Position <> FDataset.RecNo) Then
sbScroll.Position := FDataset.RecNo;
//SetStatus(Status(True));
End;
// Hook this to your TDataSource.OnStateChange
Procedure TFrameGrid.dsGridStateChange(Sender: TObject);
Begin
If dsGrid.State = dsBrowse Then
Begin
UpdateScrollbar;
//UpdateMemo;
End;
End;