Recent

Author Topic: Any Grid versus TKGrid Smooth Scrolling  (Read 5780 times)

jwhitten

  • Jr. Member
  • **
  • Posts: 61
Any Grid versus TKGrid Smooth Scrolling
« on: September 20, 2013, 04:30:40 pm »
Howdy,

I have been working on an application which makes heavy use of db grids. I have been using TRxDBGrids but have noticed that they don't seem to scroll correctly. Upon investigation, I find the same behavior in nearly all of the various Grid/DBGrid's out there except for TKDBGrid. I understand from reading what I can find that the first group are all essentially based upon TDBGrid whereas TKDBGrid is not.

The scrolling behavior in question is when you have, say, several screenfuls worth of data and use the scrollbar handle to pull/drag up or down the grid. On the TKDBGrid it scrolls very smoothly and follows the handle-- EXACTLY the behavior I want and expect. However, on all of the TDBGrid-based grids, it does not do this, but rather you pull the handle a bit and then when you let go it updates the grid all at once.

I can sort of understand this behavior for a "virtual" type of grid where the ultimate size of the grid is not known. But when the size *is* known, and/or there is sufficient off-screen buffer available for several additional screenfuls, why don't the TDBGrids scroll smoothly?

Is this a "virtual" grid type of problem? Are there some settings I should be using to obtain smooth scrolling in the TDBGrid-based grids? I am fine in all other respects (that I know of) with the TDBGrid-based grids, but this particular quirk is about to be a show-stopper as far as I'm concerned unless I can find a reasonable way to work around the issue.

Can anybody offer any advice or suggestions??

Thanks!!

John Whitten
Some programmers seem Blaise about Pascal...

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Any Grid versus TKGrid Smooth Scrolling
« Reply #1 on: September 20, 2013, 04:54:47 pm »
It's a known problem with dbgrid; see e.g. this forum thread
http://forum.lazarus.freepascal.org/index.php/topic,17615.0.html
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

jwhitten

  • Jr. Member
  • **
  • Posts: 61
Re: Any Grid versus TKGrid Smooth Scrolling
« Reply #2 on: September 20, 2013, 05:44:11 pm »
Thanks for the pointer!

Some programmers seem Blaise about Pascal...

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1269
Re: Any Grid versus TKGrid Smooth Scrolling
« Reply #3 on: September 21, 2013, 02:51:39 am »
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...

Code: [Select]
// 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;

« Last Edit: September 21, 2013, 03:42:54 am by Mike.Cornflake »
Lazarus Trunk/FPC latest fixes on Windows 11
  I'm getting old and stale.  Slowly getting used to git, I'll get there...

 

TinyPortal © 2005-2018