In recent blog posts I covered Delphi's RTL core expression engine and components binding. Now we can make an additional step and look into a key component for the entire bindings architecture, called BindingsList. A binding list is a collection of different types of bindings expressions, managed in the designers. 

In other words, the expressions and component bindings I defined in source code in the last blog post, can be fully defined in the designers (and wizards) of the BindingsList component. Just drop a component of this type to a form plus a few visual components (in my example two edits, a spin edit and a progress bar -- see image below).

The BindingsList component has a designer which allows to define a collection of bindings. Each binding can be picked using one of the many available options (way too many to explore in this article and primarily focused on data source and data field bindings). The two basic options I'm going to use here are TBindExpression and TBindExprItems.

After you select one of those bindings, let's say a TBindExpression, you need to interact with two different design surfaces to work on the expression: on one side you can configure the expression properties in the Object Inspector, like the SourceComponent and the ControlComponent (the term use to refer to the target control) and the related expressions; on the other by double clicking on the expression in the BindingList editor you can open us a special expression designer, which in turn has additional items editors and viewers:

In the image above, you can see that I connected the expression to a source and target control, but I still haven't defined an expression. This can be as simple as a single property name or a more complex combination of values and expressions and can be configured in the Object Inspector expressions properties for the binding or on the special designer displayed above. The designer also offers the option to evaluate and inspect different expressions.

Going back to the expressions, we can simply use Value and Position for the Spin Edit and the Progress Bar, respectively. Notice the binding expression has a direction (by default, source to control) that can be reversed or can also be bi-directional.

I've used a bidirectional expression for the two edit boxes, so that typing in any of them copies the content to the other. In this second example, I've used a TBindExprItems binding (but a regular expression would have been enough). This is a more complex binding, in which you specify source and control (as above) but define a collection of clear and format expressions, which can involve multiple properties of the controls. In this example, the mapping is Text to Text (bidirectional) as you can see below:

With all of this, the only Delphi code that's needed in the application is a call to re-evaluate the bindings when the value of the source changes. This is easily done by handling the OnChange events of the various controls and triggering a general update of the bindings for the current control (the Sender):

TBindings.Notify(Sender, '');

This is the very simple application in action:

Now you might be wondering where all of this configuration settings end up... but like most other design time configurations in Delphi it is not a black for for a form file you can view as text (and edit, if you know what you are doing). You can also copy the component from the designer and paste it as text, like I've done here:

object BindingsList1: TBindingsList
  Methods = <>
  OutputConverters = <>
  object BindExprItemsEdits: TBindExprItems
    Category = 'Binding Expressions'
    ControlComponent = Edit1
    SourceComponent = Edit2
    FormatExpressions = <
      item
        ControlExpression = 'Text'
        SourceExpression = 'Text'
        Direction = dirBidirectional
      end>
    ClearExpressions = <>
    NotifyOutputs = False
  end
  object BindExpression1: TBindExpression
    Category = 'Binding Expressions'
    ControlComponent = ProgressBar1
    SourceComponent = SpinEdit1
    SourceExpression = 'Value'
    ControlExpression = 'Position'
    NotifyOutputs = False
    Direction = dirSourceToControl
  end
end

That's all for now, even if I realize I just scratched the surface of the bindings architecture. The next step of these series on expressions and bindings is the Visual Live Binding designers, which builds on the pieces we are seen so far. I'll cover it next time.