Professional Documents
Culture Documents
1
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDbEBB IBAN BE18 7370 2489 2465
Table of Conents
Introduction 5
What are LiveBindings ? ................................................................................5 So, LiveBindings are just some form of Data Aware controls ?................5 Ok, which problem do LiveBindings solve then ? ........................................5 And how do LiveBindings Work ? .................................................................5 Whats the difference between Managed LiveBindings and Unmanaged LiveBindings ? ........................................................................................6 Lets get on with the examples ... ..................................................................6
Introduction .....................................................................................................7 Creating the basic Application .....................................................................7 Binding the Graphical Controls to the DataSet elds................................8 The Final Application .....................................................................................9 Where is all the Magic Happening ? ............................................................9 The TBindingsList ................................................................................................9
11
Introduction ....................................................................................................11 Setting up the UI ............................................................................................11 Setting up the LiveBindings .........................................................................12 Adding a TBindingsList and creating the TBindExpression ..................12 Setting up the TBindExpression .....................................................................13 How to Manage the Bindings ? ...................................................................14 One Step Further ..........................................................................................15
3
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
17
Introduction ....................................................................................................17 Setting up the UI and TPerson class ..........................................................17 Creating and Destroying a TPerson instance ............................................18 Creating the LiveBindings from our TPerson instance to our Visual Components..........................................................................................19 Setting up the Notications ........................................................................22 There might be a better way.......................................................................23
Final Words
24
25
Embarcadero Articles & Tutorials ..............................................................25 LiveBindings Sample projects ....................................................................25 Interesting Tutorials & Articles...................................................................25
4
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
Introduction
What are LiveBindings ?
Well ... in short, LiveBindings are a technique to bind Data to a Component. Quite a lot of times they will be used to bind the data from a eld in a recordset to a property of a component on a form ...
5
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
the example we gave about the contents of a TEdit being displayed automatically in a TLabel, we would set up the TEdit as the Source object and the TLabel as the Control object. To be completely correct, every LiveBinding will have four parts :
In the case where you would want to display the Text property of a TEdit into the Text property of a TLablel, our Source Object would be a reference to the TEdit and our Source Expression would be a reference to the Text property of that TEdit. Similarly the Control object would be a reference to our TLabel, and the Control Expression is actually an expression which can be handled by the Expression Engine, and in our case will reference the Text property of our TLabel. There is one thing we will have to pay attention to though ... there are what we call Managed LiveBindings and Unmanaged LiveBindings.
6
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
7
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
Actually ... any other CDS le would be good too. The only thing we have to remember is that the TClientDataSet is now pointing to a physical location on my Windows hard drive, and this would cause a problem when running the application on the Mac. Personally I tend to copy the CDS to the Application folder and set the FileName property at Run-Time. But we can work around that by simply setting the Active property of the TClientDataSet to True and then blank out the FileName property again. This would cause the actual data to be loaded in memory and stored in de Form le (FMX or DFM le).
8
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
The TBindingsList
When double clicking on the TBingingsList you will notice a DB Links category, and in that category you will see all LiveBindings which were created for our application.
9
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
For each component we linked to a DB eld, you should nd the corresponding LiveBindings under the DB Links category. If you would double click one of the entries, you would see the Expression(s) which were generated for that LiveBinding.
10
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
Setting up the UI
We will start out by creating a new FireMonkey application. On our Form we will drop 2 TTrackBar components, a TViewPort3D component and within the TViewPort3D component we will also add a TImage3D component. Reposition all components on a form, and make one of the TTrackBar components have its Orientation set to orVertical. Additionally, make sure the Max property of both TTrackBar components is set to 360. Add 2 additional TLabel components to your form, and set the text property of one label to XAxis and another TLabel to YAxis. As you will see in the screenshot, I have renamed some of my components (The horizontal Trackbar is called tbrXAxis, the vertical Trackbar is called tbrYAxis, and the label with the XAxis text is called lblXAxis and of course the label with the YAxis text is called lblYAxis). I would strongly encourage you to name those 4 components in the same way, so it is easier to follow the screenshots. Make sure you load an Image into the Bitmap property of the Image3D. Personally I used our companys Logo, but you can use any image you want. Reposition your controls so the UI should look similar to this :
11
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
The nished UI
13
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
procedure TForm1.tbrYAxisChange(Sender: TObject); begin BindingsList1.Notify( tbrYAxis, '' ); end; procedure TForm1.trbXAxisChange(Sender: TObject); begin BindingsList1.Notify( tbrXAxis, '' ); end;
This code will inform the LiveBindings system that something changed on the tbrXAxis and tbrYAxis. Of course you could use one single event handler to inform the LiveBindings system of a change to both TTrackbars and pass the Sender along :
14
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
A more complex SourceExpression The SourceExpression is "XAxis Value=" + Format("%f",Value) and this will be evaluated at Run-Time. So when the application runs the LiveBindings system will get the value of the tbrXAxis trackbar, format that as a string, concatenate it with the XAxis Value= string and use the result of that expression and put it into the Text prooperty of the lblXAxis TLabel. Now it should be a piece of cake to set up a similar TBindExpression in order to display the Position of the tbrYAxis TTrackBar into the second label.
15
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
16
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
type TPerson = class( TObject ) private FLastName: String; FFirstName: String; procedure SetFirstName(const Value: String); procedure SetLastName(const Value: String); public property FirstName : String read FFirstName write SetFirstName; property LastName : String read FLastName write SetLastName; end;
Use SHIFT + CTRL + C on the declaration of the class to complete the class under the cursor and you should have the basic implementation of your class.
17
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
Now add ve TLabel components and two TEdit components to your form. Rename and reposition them according to the following screenshot :
Our TObject LiveBindings form As you can see, I gave the components a descent name. Once I create my LiveBindings at runtime I will have a clear idea what the purpose will be of each component.
TForm1 = class(TForm) ... private { Private declarations } FPerson : TPerson; public { Public declarations } constructor Create( aOwner : TComponent ); override; destructor Destroy; override; end; var Form1: TForm1;
18
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
implementation {$R *.fmx} ... { TForm1 } constructor TForm1.Create(aOwner: TComponent); begin inherited Create( aOwner ); FPerson := TPerson.Create; FPerson.FirstName := 'Stefaan'; FPerson.LastName := 'Lesage'; end; destructor TForm1.Destroy; begin FreeAndNil( FPerson ); inherited Destroy; end;
Creating the LiveBindings from our TPerson instance to our Visual Components
So ... by now we have a TPerson instance, but it would be nice if we could bind the properties of that instance to the edit boxes and labels on our form. In order to do this ... we will have to create a Managed binding. There are a few different approaches, and I tried a few of them. Sadly the only one I could get working in both directions is by creating your own ManagedBinding for each individual binding. In our case we will have to create 7 different bindings to get everything working correctly :
2 Bindings to display our FirstName and LastName in the two Edit Boxes 3 Bindings to display the FirstName, LastName and a combination of the two in the Label components 2 Bindings for the other direction, so to bind the contents of our 2 Edit Boxes back to the FirstName and LastName properties of our TPerson instance.
19
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
procedure TForm1.CreateManagedBindings; begin TBindings.CreateManagedBinding( [ TBindings.CreateAssociationScope( [ Associate( FPerson, 'aPerson' ) ] ) ], 'aPerson.FirstName', [ TBindings.CreateAssociationScope( [ Associate( lblPersonFirstName, 'lblPersonFirstName' ) ] ) ], 'lblPersonFirstName.Text', Nil ); TBindings.CreateManagedBinding( [ TBindings.CreateAssociationScope( [ Associate( FPerson, 'aPerson' ) ] ) ], 'aPerson.FirstName', [ TBindings.CreateAssociationScope( [ Associate( edtFirstName, 'edtFirstName' ) ] ) ], 'edtFirstName.Text', Nil ); TBindings.CreateManagedBinding( [ TBindings.CreateAssociationScope( [ Associate( FPerson, 'aPerson' ) ] ) ], 'aPerson.LastName', [ TBindings.CreateAssociationScope( [ Associate( lblPersonLastName, 'lblPersonLastName' ) ] ) ], 'lblPersonLastName.Text', Nil ); TBindings.CreateManagedBinding( [ TBindings.CreateAssociationScope( [ Associate( FPerson, 'aPerson' ) ] ) ], 'aPerson.LastName', [ TBindings.CreateAssociationScope( [ Associate( edtLastName, 'edtLastName' ) ] ) ], 'edtLastName.Text', Nil ); TBindings.CreateManagedBinding( [ TBindings.CreateAssociationScope( [ Associate( FPerson, 'aPerson' ) ] ) ], 'aPerson.LastName + " " + aPerson.FirstName', [ TBindings.CreateAssociationScope( [ Associate( lblPersonFullName, 'lblPersonFullName' ) ] ) ], 'lblPersonFullName.Text', Nil ); TBindings.CreateManagedBinding( [ TBindings.CreateAssociationScope( [ Associate( edtFirstName, 'edtFirstName' ) ] ) ], 'edtFirstName.Text', [ TBindings.CreateAssociationScope( [ Associate( FPerson, 'aPerson' ) ] ) ], 'aPerson.FirstName', Nil );
20
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
TBindings.CreateManagedBinding( [ TBindings.CreateAssociationScope( [ Associate( edtLastName, 'edtLastName' ) ] ) ], 'edtLastName.Text', [ TBindings.CreateAssociationScope( [ Associate( FPerson, 'aPerson' ) ] ) ], 'aPerson.LastName', Nil ); TBindings.Notify( FPerson, '' ); end;
The code will probably look a bit complex. but in essence we create a Managed Binding. For every binding we create, we also create an Input and an Output association. This is where we will link an actual object to a variable we will use in our binding. And nally we also add a Source and Control expression. So lets analyze the rst binding :
TBindings.CreateManagedBinding( [ TBindings.CreateAssociationScope( [ Associate( FPerson, 'aPerson' ) ] ) ], 'aPerson.FirstName', [ TBindings.CreateAssociationScope( [ Associate( lblPersonFirstName, 'lblPersonFirstName' ) ] ) ], 'lblPersonFirstName.Text', Nil );
First thing we do is a Source Asssociation. We associate a physical instance of our FPerson instance and we will associate that with the aPerson variable. So everytime we use aPerson in our Expression, the LiveBindings system will know we are talking about the FPerson instance. Next up is our Source Expression, in our case aPerson.FirstName. When the LiveBinding System processes this, it will check the Source Associations to see if we have created an association for aPerson. The next two things are similar to the rst to, but for the Controle Object and Control Expression. We also create an association between a phisical object / component and a variable we will be using in the expression.
21
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
If you take a closer look at the Binding Expressions, you will notice an expression aPerson.LastName + + aPerson.FirstName. Since we created an association for the aPerson variable and linked that to our FPerson instance, the LiveBindings system will take the value from the FPerson.LastName property, add a space, add the FPerson.FirstName and take that result to populate the lblFullName.Text. It might look complicated at rst, but once you get a feel of the Source and Control components and their expressions you will see it is actually pretty easy and quite powerful. To try it out ... simply add a call to this CreateManagedBindings method in our Constructor right after we created our FPerson instance.
constructor TForm1.Create(aOwner: TComponent); begin inherited Create( aOwner ); FPerson := TPerson.Create; FPerson.FirstName := 'Stefaan'; FPerson.LastName := 'Lesage'; CreateManagedBindings; end;
22
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
This will make sure we inform the LiveBindings system that something got changed in our Edit controls. If you run the application right now and change soemthing in one of the Edit boxes, you will see that the TLabel components get updated accordingly. But we have one more issue to tackle. Changing the properties of our TPerson instance at runtime wont update the corresponding TLabel and TEdit components. In order to do this, we will have to react on a change in our properties too. Update the Property setters so your code looks like this :
procedure TPerson.SetFirstName(const Value: String); begin if ( Value <> FFirstName ) then begin FFirstName := Value; TBindings.Notify( Self, '' ); end; end; procedure TPerson.SetLastName(const Value: String); begin if ( Value <> FLastName ) then begin FLastName := Value; TBindings.Notify( Self, '' ); end; end;
23
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
Final Words
Conclusion
LiveBindings are a new technique to bind just about anything to a visual component and vice versa. They might look a lot more cumbersome and harder than the traditional data-aware components we have been used to since the early Delphi Days. But they are also a lot more powerful !
24
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465
25
Devia Boekweitbloemstraat 9 9940 Ertvelde tel + 32 497 55 34 18 info@devia.be www.devia.be BTW BE 0899.972.037 RPR Gent KBC 737-0248924-65 BIC KREDBEBB IBAN BE18 7370 2489 2465