We help IT Professionals succeed at work.

DBGrid and DataSource

ginsonic
ginsonic asked
on
I need to hook before and afterscroll events in my CustomDBGrid. Something alike :

DataLink.DataSet.BeforeScroll:= MyProc1;
DataLink.DataSet.AfterScroll := MyProc2;

I try to do this in Create procedure but look like DataSource isn't created. Yet .

Where can I do that ?
Comment
Watch Question

Commented:
I am assuming that you are refering to the Create of your Form. I'd suggest that you move it to the OnShow event instead, since Create will occasionally cause timing issues, since what you are trying to reference may or may not have been instanciated yet. OnShow guarantees that all the Form's elements are ready to display.



Good luck!!

Author

Commented:
No . I refer to CustomDBGrid procedure . Else was to easy :)

Commented:
Alternately you might do something like this:

program Project2;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {CustomerData: TDataModule};

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TCustomerData, CustomerData);
  CustomerData.DataLink.Dataset.AfterScroll:=Unit2.Proc1;
  CustomerData.DataLink.Dataset.BeforeScroll:=Unit2.Proc2;
  Application.Run;
end.




Good luck!!

Author

Commented:
I maked a transparent DBGrid . Work fine for a single DBGrid .
But when I use 2...n grids for same table , I have problems with painting. So I need to handle this events to force the refresh .

Commented:
aha... So why don't you scope the DataSet globally and create them in the constructor of the CustomDBGrid?

Example:


dsQry:TQuery;
Procedure Proc1;
Procedure Proc2;
 

/// constructor of CustomDBGrid

begin
  DsQry:=TQuery.create;
  With DsQry do
  begin
    BeforeScroll:=Proc1;
    AfterScroll:=Proc2;
  end;
  Inherited;
end;




Good luck!!

Author

Commented:
Don't work :(
The Proc1 and Proc2 aren't used .

Commented:
Look, quick example:

procedure TForm1.Button1Click(Sender: TObject);
var Qry:Tquery;
begin
    Qry:=TQuery.create(self);//create a dataset
    With Qry do
    begin
     AfterScroll:=MyAfterscroll; //assign the event handler
     Databasename:='Tracs';
     Sql.clear;
     Sql.add('Select * from OriginCodes');
     Open;
    end;
end;

procedure TForm1.MyAfterScroll(DataSet: TDataSet);
begin
  ShowMessage('I''ve been scrolled');//just a message in the event
end;




This works.... what are you doing?

Author

Commented:
Can you put these line into a CustomDBGrid ?
And I need to use the specified DataSource into component property .
I'm interested to know in DBGrid when the user navigate through table .

I will increase to 100 points .

Thanks for support,
Nick

Commented:
a very simple example that does what you're asking:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls,dbgrids,db,dbtables;


Type
  TmyGrid=class(TCustomDBGrid)
  ds:TDataSource;
  Qry:TQuery;
  Private
  protected
   Procedure BScroll(DataSet:TDataset);
   Procedure AScroll(DataSet:TDataSet);
  public
    Constructor Create(Aowner:TComponent);override;
  end;




type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  MyGrid:TmyGrid;
implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin

end;

{ TmyGrid }

procedure TmyGrid.AScroll(DataSet: TDataSet);
begin
    ShowMessage('Before Scroll');
end;

procedure TmyGrid.BScroll(DataSet: TDataset);
begin
     ShowMessage('After Scroll');
end;

constructor TmyGrid.Create(Aowner: TComponent);
begin
  inherited;
  ds:=TDataSource.Create(self);
  Qry:=TQuery.Create(self);
  with Qry do
  begin
    Databasename:='Tracs';
    Sql.clear;
    AfterScroll:=ASCroll;
    BeforeScroll:=BScroll;
    Sql.Add('Select * from OriginCodes');
  end;
  ds.Dataset:=Qry;
  self.DataSource:=ds;
  Qry.Open;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MyGrid:=TMyGrid.Create(self);
  MyGrid.Parent:=self;
end;

end.



Senior developer
Commented:
Hi all!

ginsonic,
if you are going to create your own DBGrid and repaint it every time after data scrolled, then override Scroll method.

    procedure   Scroll(D : integer); override;

It should help.

-----
Igor


Author

Commented:
ITugay , look like your idea is the best for me . One question, when I override the Scroll procedure I don't affect anything ? I see that the vcl procedure contain a lots of lines . I must add these to my overrided procedure ?

Sorry for my stupid question , but I'm an amateur programmer and still learning .

Regards,
Nick

P.S. I tested with Loaded too, but no good result .
Igor UL7AAjrSenior developer

Commented:
Hi ginsonic,

there should be no any problems with Scroll overriding, just do not forget to call "Inherited" method first.
Something like this:


TSomeGrid = class(....)
    procedure   Scroll(D : integer); override;
end;

....

procedure   TSomeGrid.Scroll(D : integer);
begin
  Inherited;
  //
  // do your stuffs here
  //    
end;

------
Igor.

Author

Commented:
Sorry for wrong information.
In fact Scroll is called after BeforeScroll event . Not good .

Author

Commented:
DrDelphi , in your code you specified the name of database. I don't know the used name :( or the used tables .

Author

Commented:
OK Igor . Finally have found a way . Using your idea of course . So take the points :)

Author

Commented:
Increased to 100 points, how I promise .

Author

Commented:

With Scroll I can hook now the table navigation except when press Home or End keys .

Look like First and Last don't use Scroll procedure . Any idea how to hook this events ? I have try with KeyDown but work just for the focused DBGrid :(

Offer anothers 50 points.

Thanks in advance,
Nick
Igor UL7AAjrSenior developer

Commented:
hi ginsonic,

>> Look like First and Last don't use Scroll procedure.

yes, it is. I will try to do something with it.

btw, there is WM_PAINT message. It seems like it appears after dataset go to the First or Last row.
And one more, why don't you use WM_PAINT message to perform your own drawing?

-----
Igor.

Author

Commented:
Can't use it . I use some codes to eliminate the flickering and have problems if I type there these lines .