Solved

Creating an onChange event for a class

Posted on 2002-04-10
14
437 Views
Last Modified: 2013-11-23
I have the following class declared:

type dbEntry = class(TObject)
public
  Problem : string;
  Chapter : string;
  Section : string;
  PointValue : string;
  Time : string;
 
  procedure splitInfo(source : TObject);
  procedure loadLargeData(source : TObject);
  procedure clearLargeData;

private

   endPoint,startPoint : integer;
   input : string;

end;

I want to be able to have an onChange event for this class, so that whenever any of the values stored in the variables changes, a procedure can be called.  The idea, is that whenever the user enters a new value into one of them, I want the new values posted to a corresponding dbTable immediately. Instead of doing this manually at every point in the code where the user might change one of the values, I would like an onChange event for the class that takes care of it.

any thoughts?

chmod101
0
Comment
Question by:chmod101
  • 6
  • 4
  • 4
14 Comments
 
LVL 1

Expert Comment

by:h_mohsenian
Comment Utility
< add this code to Private section >

FOnChanged        : TNotifyEvent;

< add this code to public section >

property OnChanged : TNotifyEvent read FOnChanged write FOnChanged;

< Now u have an Event >


< add this code to ur set Value Procedures ?

if Assigned(FOnChanged) then FOnChanged(Self);

< But at first u should make some set value procedures like this  >

< add this code to ur private section >
< we suppose it is an Integer Data >

 FMyData : Integer;
 procedure SetMyData(Val : Integer);

< add this code at public section

 property MyData : Integer read FMyData write SetMyData ;


< now u have an OnChange Event >
but
u can make ur Event Type : if u need more than ( Sender : TObject ) bye a little code . TNotifyEvent and other events are just some "Procedure" types. see Delphi help.

also it is better for u to make this Event as Published not pubil section. although at public section you shuld refer a Function to that TNotifyEvent.

I am ready to more comments;
Hamed


0
 
LVL 1

Expert Comment

by:h_mohsenian
Comment Utility
about ur own Event type , see that TNotifyEvent has the follow type :

type TNotifyEvent = procedure (Sender: TObject) of object;

infact an Event is a <Procedure() of object;

therfore u can make a new Event type :

Type
TMyEvent = procedure ( Sender : TObject; MyNewData : Integer ) of Object;

therefore at ur setMyData() procedure you should do it :

if Assigned(FOnChanged) then FOnChanged(Self,MyNewData);
                                         |       |
                                         |       |
                                        Sender   Data

Hamed ;-)
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
hi hamed,
how are you?
(sorry to be off topic)
meikl ;-)
0
 
LVL 1

Expert Comment

by:h_mohsenian
Comment Utility
hi Meikl ;-)

very nice to see u again :-) how are you and your family , specialy the nice Children :-) ?

I was graduated last month. and taked the MS enterance exam last month too. now I am working in a Team at a Automation Co. , we are designing a Distributed PC Based Automation System - Like my BS univ. project - but unfortunately by VC++ not Delphi :-( They did not Accpect Delphi! . in general I am still alive ;-)

what are u doing ? I am sure u are completely successful in ur work and ur life .

Hamed;-)
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
hamed,
i write a email to you,
is the email-adress at your profile correct?
meikl ;-)

(sorry to be off topic)
0
 
LVL 1

Expert Comment

by:h_mohsenian
Comment Utility
Meikl,

Yes It is Correct , also h_mohsenian@yahoo.com

Thanks for your favours.
Hamed

(sorry to be off topic)
0
 

Author Comment

by:chmod101
Comment Utility
Well, Harmed, thank you for the help, but that wasn't very clear.  Could you include a small example, without any comments, on where exactly to place this stuff?  I have never done anything like this, and I dont really understand how to use the setValue procedure.

Could you post a brief example of a class with an onChange event included?

Thanks for your help,
chmod101
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
hamed, i'm a lazy mail-writer, i know :-)
but mail is in work ;-)
0
 
LVL 1

Accepted Solution

by:
h_mohsenian earned 30 total points
Comment Utility
hi chmod101 ,
Sorry, Maybe u r right ;-)

now : I wana suggest u to make ur New Class at the Base of <TComponent> not <TObject> therefore u will see ur Result easily and .... :

1. Go to < Component Menu >
2. Select < New Component >
3. Choose ( or write ) <TComponent> at <Ancestor Field>
4. Write <TdbEntry> at <Class Name> Filed
5. accept other defualt Values and Click on <OK> buttom
6. Now u have a Unit page
7. write this code at that page :
// ------------------- Starts Unit dbEntry ---------
unit dbEntry;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TMyEvent = procedure ( Sender : TObject; MyNewData : Integer ) of Object;

  TdbEntry = class(TComponent)
  private
    FMyData : Integer;
    FOnChanged : TMyEvent;
    procedure SetMyData(Value : Integer);
    { Private declarations }
  protected
    { Protected declarations }
  public
    property MyData : Integer read FMyData write SetMyData ;
    { Public declarations }
  published
    property OnChanged : TMyEvent read FOnChanged write FOnChanged;
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Hamed', [TdbEntry]);
end;

procedure TdbEntry.SetMyData(Value : Integer);
begin
  FMyData := Value;
  if Assigned(FOnChanged) then FOnChanged(Self,Value);
end;

end.

// ------------------- Ends Unit dbEntry ---------

8. Save this File .Now u should Install this New Component
9. Go again to <Component Menu> and Click on <Install Component >
10. use all defualt Settings and Install ur New Component.
11. save all opended Files and after that Close all of them.
12. Open a New Application
13. u will see ur New Component at 'Hamed' Tab of Component List ( up and Right at Delphi Page )
14. select it and Drop it on ur Form
15. go to the Event Tab of this new Object ( at Object Inspector )
16. u will see an OnChanged Event
17. Use it and test it in every Case that u want but there is an Example for this Test :


// -------------------- Example Code Starts --------------------
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  dbEntry, StdCtrls;

type
  TForm1 = class(TForm)
    dbEntry1: TdbEntry;
    Button1: TButton;
    procedure dbEntry1Changed(Sender: TObject; MyNewData: Integer);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.dbEntry1Changed(Sender: TObject; MyNewData: Integer);
begin
  showmessage('New Value is' + IntToStr(MyNewData));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  dbEntry1.MyData := 10;
end;

end.

// -------------------- Example Code Ends --------------------

BUTTTTTTT, if u want TObject as ur Base class I guess u can not Use Published and Object Inspector ....... therefor u shoul make that Event Property at <Public> mode , instead of <published> mode. and u shoul refer a Procedure in Type of  TMyEvent to that Event of Ur Object BY CODE ( not easy like Object Inpector ). But as a general suggestion I recommend u to us TComponent . It is easy to use. ;-)

also Mikle can Help us to for more comments ;-)

I hope it will be help full for u ;-)
Hamed






Hi Meikl ,

:-)) Take It easy . :-)) Do you Remember my Antient email About IRAN!! ;-) I am waiting for ur emails every times. Thanks for ur favours. u are a good friend and always care ur Little Student ( Hamed ) .

Hamed ;-)  
0
 

Author Comment

by:chmod101
Comment Utility
Alright,

Thanks for the clarification, but I still have a problem. The type of data you used was an integer.  I need to use a class. I have about 30 different fields of data that need to be grouped together, and anytime anyone of them gets changed, I want to call the onChange event.  My thought was to create a class,dbData, that groups all of these, and then insert dbData where you have integer. So, FMyData becomes of dbData type, and so on. It worked, and the unit compiled and was added succesfully, however, it wont work.

It doesnt allocated memory for the class, so when you try to assign a value to one of its members, it causes an access violation.  So, how do I do this without having to write an onChange event for all 30 db Fields?

chmod101
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
you should raise the points a bit,
because you're about to expand
the context of your question

normally you code for each attribute
a set procedure and a get procedure
to have properties (if you want to publish it)


you could call in each set procedure a procedure
maybe called changed, which then check and calls the assigned onChange procedure

hameds sample is for one attribut,
you have to expand it to the other attributs
of your class

like

procedure TdbEntry.SetProblem(Value : String);
begin
 if value <> Problem then
 begin
   Problem := Value;
   Changed;
 end;  
end;


procedure TdbEntry.SetChapter(Value : String);
begin
 if value <> Chapter  then
 begin
   Chapter  := Value;
   Changed;
 end;  
end;

// and so on

procedure TdbEntry.Changed;
begin
  if Assigned(FOnChanged) then
    FOnChanged(Self);
end;

meikl ;-)


0
 

Author Comment

by:chmod101
Comment Utility
Thanks for the help,

If I have any more questions, I will post them.

chmod101
0
 
LVL 1

Expert Comment

by:h_mohsenian
Comment Utility
Hi and thanks for the Points,

I guess meikl's code is clear and perfect for your question. but we are ready for more help.

Hamed ;-)

0
 

Author Comment

by:chmod101
Comment Utility
hey, I am about to post another question which is an extension of this topic. check it out.


chmod101
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
This video discusses moving either the default database or any database to a new volume.
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

728 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

10 Experts available now in Live!

Get 1:1 Help Now