If a data element or a UI control changes state in your application, you may want multiple actions to occur. For example, when I change tabs in a TTabContol, I want a number of UI controls to also change - this is the perfect job for a TBindExprItems LiveBinding. This component groups ‘linked’ expressions together and executes them.
Let’s create a new FireMonkey HD Application, Save All (FDamoExprItems.pas and ExprItemsDemo.dpr) and add some controls to see this behaviour:
In your application add the following UI controls and lay them out to something similar as follows:
- TTabControl: Name:= tcTabDemo, add 5 TTabItems to tcTabDemo using the ‘Add Item’ link at the bottom of the Object Inspector
- TEdit: Name := edtTabStatus
- TProgressBar: Name := pgTabStatus, max := 4
- TTrackBar: Name:= tbZoomy, max := 4
With our UI controls laid out on the form, it is now time to create our LiveBinding. The functionality that I want to implement is when the user switches to a new tab, I want edtTabStatus to display the Tab Index that is currently selected, pgTabStatus to reflect the Tab Index that is currently selected and tbZoomy to also display the currently selected Tab Index. From the Tool Palette, find and drop a TBindingsList on the form (Name := blExpressionItems) double click to display the Expression Editor, click the New icon in the top left hand side of the Expression Editor and choose TBindExprItems and click Ok.
The first thing that we need to set up is the Source and Control objects. In our scenario I want to capture the current TabItem that is selected so the source object is tcTabDemo. I’m going to have multiple control objects so for now I will set the control object as edtTabStatus. We set these by selecting our LiveBinding in the open editor and from the Object Inspector set the ControlComponent and the SourceComponent.
With the Expression Editor still open double click your newly created TBindExprItems (Name := bxiExpressionItems) so that we can add our expressions. You will notice a slight difference between this editor and the TBindExpression editor that we looked at previously. On the left side of the Editor we have two ‘types’ of expressions that we can create - Format expressions and Clear expressions. Format expressions involve displaying our source data in our control object. Clear expressions also format our control object but will only get called when the LiveBinding is deactivated.
We will create the Format expressions first. Make sure that the Format type is selected on the left hand side of the Expression Editor, click the New button in the top left hand corner and set the Control Expression as Text and the Source Expression as "Tab Index: " + ToStr(TabIndex). What we are basically doing here is converting the TabIndex property of tcTabDemo to a String and then appending it to the static string "Tab Index: " and displaying this in the Text property of edtTabStatus.
Create a second Format expression, set the Source Expression to TabIndex and set the Control Expression to Owner.tbZoomy.Value. This is really cool! With my expression, I can use the Owner property of edtTabStatus and then access the Value property of tbZoomy.
Create a third and final Format expression by setting the Source Expression to TabIndex and the Control Expression to Owner.pgTabStaus.Value. We have now created three Format expressions all based on the single source of TabIndex from tcTabDemo.
Let’s create a Clear expression to show how these type of expressions work in an application. When the LiveBinding is not active, I want edtTabStatus to display the text ‘0′. Select the Clear type in the left hand side of the Expression Editor, click the New button in the top left hand corner and set the Source Expression to 0 and the Control Expression to Text.
Close all of the editors so that we are back to the Form. Now we need to trigger this LiveBinding. As from our first examples, this LiveBinding will fire when the source object changes, in this case, tcTabDemo. Create an OnChange event handler and enter in the following line of code:
Save what we have implemented and run the application. When you select a TabItem, edtTabStatus, pgTabStatus and tbZoomy should all reflect which TabItem you have selected.
Finally, let’s see the effect of the Clear expression that we created. Create an OnCreate event for your form and add the following line of code:
bxiTabControl.Active := false;
This will deactivate our LiveBinding when the application starts. In order to enable the LiveBinding add a TCheckBox to the first TTabItem page (Name := cbEnableBinding), create an OnChange event and add the following lines of code:
if cbEnableBinding.Enabled then bxiTabControl.Active := true
Rerun the application and notice that edtTabStatus now contains the value ‘0′. Flick through the tab pages and you will see that noting happens. Jump back to the first TabItem and enable cbEnableBinding - you should now see that the LiveBinding is active and working as expected.
In wrapping up, I hope that you can see that TBindExprItems builds on the simple TBindExpression by providing the ability to have more than one control object involved when the source object is modified and also the ability to clear the contents of our control objects when the binding is no longer active. I hope that you can also see that from a coding perspective we have simplified our UI code by abstracting the logic required to associate data and/or state changes to and from our UI objects. This flexibility means that I can add and remove control objects without disrupting any of the UI code.