Contents
Preface
In addition to what was shown in SmartBinding with kbmMW #5, more features will be included in next release of kbmMW.
This blogpost will show a demo of 3 of them, states, sub properties and date time binding.
A demo of the 3 new SmartBinding features in concert
This demo shows easy designtime binding of date time values for displaying a real time clock in various formats, via a bound TkbmMWDateTime field in a record, and binding between an TEdit to another TkbmMWDateTime field in a record, showing easy input and validation.
So how is it done?
The real time clock demo
The top part (Real time clock) sample is done by making a TkbmMWDateTime instance available, in this case in a record. However it could have been made available as part of a class instance which probably would be a more usual usecase.
TTest2 = record timestamp:TkbmMWDateTime; edittimestamp:TkbmMWDateTime; end; TMyForm = class(TForm) private FDateTimeData:TTest2; ... end;
As is a recommended strategy, I also defined a binding placeholder for the FDateTimeData, so we can refer to that name rather than the FDateTimeData instance directly.
In this sample, this is done in the OnCreate event of the form.
Binding.DefineData<TTest2>('datedata',FDateTimeData,true);
The above definition’s true argument, tells kbmMW’s SmartBinding that SmartBinding should store a reference to the record, rather than the record itself. This is particularly important for record types, since they are by default copied when moved around, and copying it means that the one in the form is going to be different from the one handled by the binding system, which means that changes in one is not seen by the other.
However when it is defined as a reference, it will be that particular record instance that will be used by all parties.
Class instances are always refered to by reference regardless of if the true argument is provided or not.
Then I have define a scheduled event, that updates the time every second, so we have a real time clock to display.
Scheduler.Schedule(procedure begin FDateTimeData.timestamp.Local:=TkbmMWDateTime.Now.Local; end).EverySecond.Synchronized.Activate;
Finally a couple of TLabel controls has been added to the form, with the purpose of displaying the timestamp in various ways.
Each label have a caption set that is used for automatic binding by kbmMW. The top label will display the content of the field called timestamp from the data defined by the binding data placeholder named datedata which we defined a bit further up. Since we have not told how it should be displayed, it will automatically display as a local system formatted date/time value. So its look will change according to whatever date/time locale settings your computer have (or you may have defined elsewhere in your program using Delphi’s FormatSettings).
The next label (one step down) have defined as part of its caption, that the timestamp should be formatted as a locally formatted UTC value. Again it will use your computers default settings or whatever has been setup in FormatSettings.
The bottom label’s caption indicates that the format for the date/time presentation must be ISO8601.
As shown in the other blog posts about kbmMW SmartBinding, all that is needed is to AutoBind the form.
Binding.AutoBind(self);
This is in the samples case also done in the OnCreate event of the form.
Now you will have a live clock ticking away, on your form.
Real time editing and validationof date/time values
For the next part of the demo, we will add a couple of TEdit’s and TLabel’s.
There is also a button on the demo, but the only purpose of that is to force feed a specific date into the Local time field. It is not terribly interesting for the binding demo, so we do not need that one.
The controls has their respectively Text and Caption properties set at designtime, to define which bindings kbmMW should make, when the form is autobound by the Binding.AutoBind statement (as seen above).
The Local time TEdit is simply bound to the other field of the TTest2 record, but this time twoway, which means that when we type something, that will be automatically converted and stored in the edittimestamp TkbmMWDateTime field.
The two TLabel’s are defined according to similar definition as shown in the previous sample, right above, now just displaying the contents of the edittimestamp field instead.
The really interesting TEdit control, is the one with the ISO8601 label next to it. It’s designtime binding definition is somewhat longer, so I will show that here:
[{@datedata.edittimestamp, dateTimeStyle:ISO8601, twoWay:true, name:bnd1},{to:'.font.color', expr: "if(ok('bnd1'),0x000000,0xFFFFFF)" },{to:.color, expr: "if(ok('bnd1'),0x00FF00,0x0000FF)" } ]
Or let me show it in a beautified format:
[ { @datedata.edittimestamp, dateTimeStyle:ISO8601, twoWay:true, name:bnd1 }, { to:'.font.color', expr: "if(ok('bnd1'),0x000000,0xFFFFFF)" }, { to:.color, expr: "if(ok('bnd1'),0x00FF00,0x0000FF)" } ]
What we can see is that this designtime binding, infact consists of an array of 3 bindings.
The first one, is similar to the other bindings we have seen. It is a two way binding between the Text property of the TEdit and the edittimestamp field. The binding has been given a name, bnd1. This name is important as we will refer to it in the other two bindings.
What I have not explained earlier, is that when you enter data into a source that needs converting to a TkbmMWDateTime value, there will automatically be made validation check. SmartBinding automatically keeps track of the outcome (true/false) of those conversion’s successes. It does so by setting a state for each and every binding you define. The state can be referered to by the bindings name and that is what we do in the two next bindings:
{ to:'.font.color', expr: "if(ok('bnd1'),0x000000,0xFFFFFF)" },
Here we bind an expression to the property color of the property font of the current control. Hence in VCL we access the font color, depending on if the latest conversion of the binding named bnd1 went ok or not. if ok, we set the font color to black (0x000000), else we set it to white (0xFFFFFF).
And similarly with the last binding, we control the background color of the current control (the VCL TEdit), making the background red or green depending on the success of the date/time conversion of the binding named bnd1:
{ to:.color, expr: "if(ok('bnd1'),0x00FF00,0x0000FF)" }
Now you have visual coloring and real time validation of your date/time input, without having written a single line of code in your application.
Obviously you could have written all this in pure Delphi code, but then you would not be able to change it without recompiling your application later on. Using kbmMW SmartBinding you could change the binding criteria simply by loading a different definition into your bindings at start up time.
Those definitions could be managed by an advanced user, to allow for changing the look and feel of your application without having to recompile it.
SmartBinding and States
Now you know there is a special “ok” state that can be queried whenever you need to, by any binding.
But you can also define your own state variables. This way you can choose to store some sort of state (string, numeric value, boolean or date/time) by some of your bindings, and access those state values in other bindings.
State’s can also be managed directly via code by using methods in the TkbmMWBindings class directly available via the global Binding instance:
function GetState(const AStateName:string):TValue procedure SetState(const AStateName:string; const AValue:TValue); procedure ClearState(const AStateName:string); procedure ResetStates;
If you want to get the OK state for the binding named bnd1 from code, you can write like this:
var bOK:boolean; begin bOK:=Binding.GetState(TkbmMWBindings.STATE_INSTANCE_OK_PREFIX+'bnd1').AsBoolean; end;
You can set and use any state as you like.
In your binding’s you can get and set states by using expressions:
{ expr: "getState('yourstatename')" } and { expr: "setState('yourstatename',data)" }
Im sure there will be some great usecases for states. For now they provide a way to include automatic validation of date/time input.
Remember… if you like kbmMW or what you read here, share it with your friends and colleagues.
Also remember you can get going totally for free by downloading kbmMW Community Edition, which can be used for teaching, personal use and even commercial use (terms apply). kbmMW Community Edition do not include source, and only supports latest version of Delphi in 32 bit mode, it however contains most features found in kbmMW Enterprise Edition except those that require compilation of the kbmMW source code.
Happy binding
Kim/C4D