Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Attach to Datasource Dataset change

Posted on 2004-04-28
11
Medium Priority
?
1,091 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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 1000 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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
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…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Suggested Courses

618 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