Solved

Attach to Datasource Dataset change

Posted on 2004-04-28
11
973 Views
Last Modified: 2010-04-05
I have an application that has many Tdatasource components.
The individual datasource components can change dataset many times at runtime.
I need to execute some code whenever this happens.
I need to create a unit that somehow attaches to the datasource dataset change property. It will perform my custom
processing then continue on with the dataset change. A code example would be good.
Any help is much appreciated.
0
Comment
Question by:RickJ
  • 7
  • 4
11 Comments
 
LVL 4

Expert Comment

by:ceoworks
ID: 10944809
Hi, When TDataSource's DataSet property changed, OnStateChange event triggers :

TForm1 = class(TForm)
private
    ..
    ..
public
  ..
  procedure DoOnStateChange(Sender: TObject);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  DataSource1.OnStateChange := DoOnStateChange;
end;

procedure TForm1.DoOnStateChage(Sender: TObject);
begin
  Caption := Caption + 'State Changed !!';
end;

Kind Regards,

Oktay Sancak
0
 
LVL 4

Expert Comment

by:ceoworks
ID: 10944818
When TDataSource's OnStateChange event triggers, our DoOnStateChange procedure is running. Because we assigned OnStateChange event to our DoOnStateChange procedure with this code :

procedure TForm1.FormCreate(Sender: TObject);
begin
  DataSource1.OnStateChange := DoOnStateChange;
end;

Cheers,

Oktay Sancak
0
 
LVL 8

Author Comment

by:RickJ
ID: 10944865
Thanks for the comment ceoworks.
The OnStateChange is triggered by many things.
I am only iinterested in the changing of datasets.
I need to know what the dataset was before it is changed and what it is being changed to.
I specifically want to attach to the dataset property change.
Any ideas??

Thanks,
Rick.
0
 
LVL 4

Expert Comment

by:ceoworks
ID: 10944913
Here is the Delphi's help files about OnStateChange :

"During the course of a normal connection to a database, a dataset’s state changes frequently. For example, each time a user starts editing a field in a data-aware control the dataset’s State property is changed from dsBrowse to dsEdit if the State is not already dsEdit. An OnStateChange event handler can respond to changes in state by taking actions such as disabling or enabling menu items or buttons."

When the OnStateChange event triggers, you can learn the current state of DataSet with "State" property.

property State: TDataSetState;

"TDataSetState indicates the current operating mode of a dataset component."

For example if DataSource.State is dsInactive, it means that dataset is closed and its data is unavailable.

--- EXAMPLE UNIT ---

AdoTable1 and AdoTable2 is connected to AdoConnection1 but they have different "TableName"s.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, StdCtrls;

type
  TForm1 = class(TForm)
    DataSource1: TDataSource;
    ADOTable1: TADOTable;
    ADOTable2: TADOTable;
    ADOConnection1: TADOConnection;
    btnSetTable1: TButton;
    btnSetTable2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btnSetTable1Click(Sender: TObject);
    procedure btnSetTable2Click(Sender: TObject);
  private
    procedure DoOnStateChange(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  StateChangeCount: integer;

implementation

{$R *.dfm}

procedure TForm1.DoOnStateChange(Sender: TObject);
begin
  Inc(StateChangeCount);
  Form1.Caption := 'DataSet State Changed ' + IntToStr(StateChangeCount) + ' times';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  DataSource1.DataSet := ADOTable1;
  DataSource1.OnStateChange := DoOnStateChange;
end;

procedure TForm1.btnSetTable1Click(Sender: TObject);
begin
  DataSource1.DataSet := ADOTable1;
end;

procedure TForm1.btnSetTable2Click(Sender: TObject);
begin
  DataSource1.DataSet := ADOTable2;
end;

end.

Cheers,

Oktay Sancak
0
 
LVL 8

Author Comment

by:RickJ
ID: 10945021
Thanks again for your comments Oktay,
The onstatechange will let me know when the dataset is changed, but I need to do processing before it is changed.

My application has around 200 forms. All of these forms are opened from the one procedure.
I was thinking that I could maybe loop through the components on the form when it is created, finding all the tdatasource
components. When I find a tdatasource component I would like to redirect its dataset change property to a custom property change.
I hope this gives a better picture of what I am trying to achieve.
Do you think this is possible ??  Any more Ideas??
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 4

Expert Comment

by:ceoworks
ID: 10945030
When i change the DataSet property in runtime like i did in my code, State is changing two times. First of all changing to dsInactive then to dsBrowse. When it change to dsInactive, old DataSet is closing then State is changing to dsBrowse and it means that new DataSet is ready to view. You can store the old value of DataSet property and then check it with State's dsBrowse property change.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, StdCtrls;

type
  TForm1 = class(TForm)
    DataSource1: TDataSource;
    ADOTable1: TADOTable;
    ADOTable2: TADOTable;
    ADOConnection1: TADOConnection;
    btnSetTable1: TButton;
    btnSetTable2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btnSetTable1Click(Sender: TObject);
    procedure btnSetTable2Click(Sender: TObject);
  private
    procedure DoOnStateChange(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  StateChangeCount: integer;
  ExDataSet: TDataSet;

implementation

{$R *.dfm}

procedure TForm1.DoOnStateChange(Sender: TObject);
begin
  if (DataSource1.State = dsBrowse) and (DataSource1.DataSet <> ExDataSet) then
  begin
    ShowMessage('DataSet Changed');
    ExDataSet := DataSource1.DataSet;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  DataSource1.DataSet := ADOTable1;
  ExDataSet := ADOTable1;
  DataSource1.OnStateChange := DoOnStateChange;
end;

procedure TForm1.btnSetTable1Click(Sender: TObject);
begin
  DataSource1.DataSet := ADOTable1;
end;

procedure TForm1.btnSetTable2Click(Sender: TObject);
begin
  DataSource1.DataSet := ADOTable2;
end;

end.
0
 
LVL 8

Author Comment

by:RickJ
ID: 10945068
Hello Oktay,
I need to do my processing when the old dataset is still actively connected to the datasource.
And then some more processing when the dataset has changed.

Thanks
Rick.
0
 
LVL 4

Expert Comment

by:ceoworks
ID: 10945304
Hi Rick,

It looks like a hard work or i'm really sleepy :) I understand what you mean. You wants to become aware before the DataSet change. Ok i'll try.
0
 
LVL 4

Expert Comment

by:ceoworks
ID: 10945460
TDataSource doesn't have a good way to do that. It looks like there isn't any way to do that before ex-dataset closed. I thought to create a new DataSource component with overriding TDataSource's SetDataSet procedure. With it we can be aware of the changes(before and after..) in DataSet property. But looks not possible because SetDataSet procedure is in the private section. TDataSet events not working too..
0
 
LVL 8

Author Comment

by:RickJ
ID: 10945615
That is exactly where I am at.
I have attempted what you were thinking and came up with the same result.
I am starting to wonder if it is possible?? My head is starting to hurt!!

Thanks for the help Oktay.
0
 
LVL 4

Accepted Solution

by:
ceoworks earned 250 total points
ID: 10948025
I don't like to say that Rick but it looks like there isn't any way to do that with TDataSource. This question doesn't have a solution in a normal way. Base component is not flexible enough so it's impossible to change. But you may think to add some events to the original VCL(TDataSource's source code..) :) Anyway..

Cheers Rick,

Oktay Sancak
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now