I. Introduction▲
La traduction littérale du mot (selon googletrad, de l'anglais vers le français) : « fixations en direct » n'est pas forcément très parlante !
Si nous remplaçons le terme de « fixations » par « liaisons » nous commençons à y voir un peu plus clair. Reste à répondre à la question « liaisons de quoi ? » Pour généraliser, je répondrai : de toute propriété d'un composant, mais avec un bémol, d'un composant avec des propriétés observables. Je reprendrai plus tard cette notion « d'observabilité ».
Les LiveBindings nous ont été proposés dès la version XE2 de RAD Studio (Delphi et C++ Builder), c'est-à-dire en même temps que FMX et inclus aussi à la VCL(1). Une des raisons essentielles de cette introduction, du moins pour FMX, était qu'il n'y a aucun composant lié aux sources de données ! Bien sûr il était possible, par code, de lier les valeurs aux composants, mais plus il y a de code, plus il y a de sources d'erreurs possibles. Les concepteurs ont donc décidé de nous « simplifier » la tâche.
Lors de la version XE3, les versions professionnelles et plus se sont vu octroyer un concepteur visuel de liaisons qui couvre la plupart des besoins d'une application « classique ». Le piège de la facilité des liaisons dites « rapides » est que si elles couvrent au moins quatre-vingts pour cent des besoins, on se retrouve quelquefois dans des impasses qu'une liaison plus « manuelle » pourrait régler. Malheureusement, peu de documentation est disponible. L'objectif principal de cette suite de tutoriels est d'essayer de faire le tour des possibilités de ces liaisons.
II. Définition rapide▲
Le LiveBinding est un mécanisme (framework) de RAD Studio qui permet d'associer les propriétés d'un objet à une expression sous la forme d'une chaîne. L'expression, évaluée lors de l'exécution du programme (runtime), peut être une propriété de cet objet, d'un autre objet, ou une formule plus complexe incluant des propriétés d'objets, des constantes littérales, des opérateurs ou des méthodes.
À retenir :
- Un LiveBinding est un objet contenant une ou plusieurs expressions ;
- Les expressions sont des phrases (formules, chaînes) qui sont évaluées par l'évaluateur d'expressions ;
- En pratique, les LiveBindings invoquent d'eux-mêmes le moteur d'évaluation pour interpréter les expressions.
III. Une utilisation simple▲
Plutôt qu'un long préambule, passons à une démonstration. L'objectif du programme est de déplacer une balle avec un curseur. La forme principale ne contiendra qu'un TShape de forme ronde et un TTrackbar. En faisant glisser le curseur, la balle se déplacera au-dessus.
L'application ne risque pas d'être inscrite dans les annales, mais elle est suffisante pour la présentation.
III-1. La méthode « à l'ancienne »▲
Avec les anciennes versions, nous utiliserons l'événement OnChange du composant TTrackbar pour réaliser le déplacement.
unit
U_Prog1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.ComCtrls;
type
TForm8 = class
(TForm)
TrackBar1: TTrackBar;
Shape1: TShape;
procedure
TrackBar1Change(Sender: TObject);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end
;
var
Form8: TForm8;
implementation
{$R *.dfm}
procedure
TForm8.TrackBar1Change(Sender: TObject);
var
percent : Double
;
posCurseur: integer
;
begin
// Méthode "Classique", Calcul décomposé pour les besoins de l'explication
// calcul du pourcentage sur la barre
Percent:=TrackBar1.Position / TrackBar1.Max;
// Calcul en pixels, Arrondi nécessaire
PosCurseur:=Round(TrackBar1.Width*Percent);
// Positionnement exact du cercle rouge
Shape1.Left:=TrackBar1.Left+posCurseur-(Shape1.Width div
2
);
end
;
end
.
Pour que vous puissiez reproduire l'exemple, je vous propose aussi le source de la fiche. En fait, ce n'est pas aussi innocent que vous pourriez le penser, ce source nous servant par la suite comme point de comparaison.
object
Form8: TForm8
Left = 0
Top = 0
Caption = 'D'#233'placer la balle'
ClientHeight = 117
ClientWidth = 447
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object
Shape1: TShape
Left = 0
Top = 8
Width = 40
Height = 41
Brush.Color = clRed
Pen.Color = clRed
Shape = stCircle
end
object
TrackBar1: TTrackBar
AlignWithMargins = True
Left = 20
Top = 69
Width = 407
Height = 45
Margins.Left = 20
Margins.Right = 20
Align = alBottom
TabOrder = 0
OnChange = TrackBar1Change
ExplicitLeft = 8
ExplicitTop = 112
ExplicitWidth = 431
end
end
III-2. En FMX▲
Mise en garde aux détenteurs d'une version starter
Malheureusement pour les détenteurs de cette version le concepteur visuel de liens n'est pas disponible (ainsi que les raccourcis y faisant accès).
Pour eux, seule la méthode « manuelle » sera accessible !
Ces points ou visuels non accessibles seront indiqués par un astérisque (*).
Pas de grand changement dans la présentation, seuls changements visuels notables :
- le TShape devient un TCircle ;
- le TTrackBar n'a pas tout à fait la même présentation ;
- et, bien sûr, pour les non habitués à FMX, cela peut surprendre que le cadre de la forme Windows ait disparu .
On pourrait, bien sûr, coder le même événement OnChange de la TTrackbar mais, et c'est quand même l'objectif, nous allons passer par les LiveBindings.
Deux possibilités s'offrent à nous :
- passer par l'expert (concepteur visuel)(2) ;
- avoir une démarche composant, en plaçant sur la forme, un TBindingsList.
Comme il s'agit dans un premier temps d'une introduction, nous utiliserons la première solution. Un petit clic droit sur la forme et la sélection de l'option « Lier visuellement... »* nous ouvre, en bas de l'écran, une fenêtre de conception visuelle.
Toutefois, si l'on voit apparaître la propriété Value pour le composant TrackBar1, pour Circle1 aucune propriété n'est accessible ! Une seconde étape est donc nécessaire : savoir quelle est la propriété que nous devons modifier et, bien évidemment, la voir apparaître dans le concepteur.
Point de propriété Left avec les composants FMX, celle-ci étant remplacée par une propriété Position.X. Un clic sur les … positionnés sous le nom du composant nous affiche une liste des membres pliables.
Après validation, nous pourrons, avec la souris, lier les deux propriétés, ce qui sera représenté par une flèche.
Que s'est-il passé ?
Sur la forme, un nouveau composant est apparu : un TBindingsList et ce dernier a même déjà un élément : LinkControlToPropertyPositionX (qui fait partie du groupe des liaisons rapides).
Les possesseurs de la version starter auront certainement compris qu'il leur faut donc déposer « manuellement » un TBindingsList et ajouter, grâce au menu contextuel, un TLinkFieldControlToProperty et remplir les mêmes propriétés renseignées par le concepteur visuel.
Bien, c'est lié, mais où mettre les calculs ?
À ce stade on peut, bien sûr, exécuter le programme, mais le comportement ne sera pas celui souhaité.
Intéressons-nous maintenant à l'inspecteur de propriétés et plus particulièrement à ce fameux élément.
On y retrouve :
- le nom du composant qui est concerné (Component) ;
- le nom de la propriété concernée (ComponentProperty) ;
- le nom du contrôle effectuant la liaison (Control).
Juste en dessous de cette dernière propriété, il y a CustomFormat. Pour cette dernière nous indiquerons notre calcul, selon la formule suivante :
Position.X + Value*Width/Max - Owner.Circle1.Width/2
Nous pouvons maintenant compiler et tester le programme et nous observerons le même comportement que le précédent.
Je reviendrai sur la formule un peu plus tard, étudions d'abord les deux sources :
unit
UFMX_Prog1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects, Data.Bind.EngExt,
Fmx.Bind.DBEngExt, System.Rtti, System.Bindings.Outputs, Fmx.Bind.Editors,
Data.Bind.Components;
type
TForm8 = class
(TForm)
Circle1: TCircle;
TrackBar1: TTrackBar;
BindingsList1: TBindingsList;
LinkControlToPropertyPositionX: TLinkControlToProperty;
private
{ Déclarations privées }
public
{ Déclarations publiques }
end
;
var
Form8: TForm8;
implementation
{$R *.fmx}
end
.
Surprise ? Pas une seule ligne de code et pourtant, cela fonctionne ! Où est passé notre calcul ? On le retrouve dans le source de la forme, c'est-à-dire dans le fichier d'extension .fmx correspondant :
object
Form8: TForm8
Left = 0
Top = 0
Caption = 'Jeu de balle'
ClientHeight = 123
ClientWidth = 549
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object
Circle1: TCircle
Fill.Color = claRed
Position.Y = 24
.000000000000000000
Size.Width = 40
.000000000000000000
Size.Height = 50
.000000000000000000
Size.PlatformDefault = False
Stroke.Color = claRed
end
object
TrackBar1: TTrackBar
Align = Bottom
CanParentFocus = True
Orientation = Horizontal
Margins.Left = 20
.000000000000000000
Margins.Right = 20
.000000000000000000
Margins.Bottom = 10
.000000000000000000
Position.X = 20
.000000000000000000
Position.Y = 94
.000000000000000000
Size.Width = 509
.000000000000000000
Size.Height = 19
.000000000000000000
Size.PlatformDefault = False
TabOrder = 1
end
object
BindingsList1: TBindingsList
Methods = <>
OutputConverters = <>
Left = 76
Top = 5
object
LinkControlToPropertyPositionX: TLinkControlToProperty
Category = 'Liaisons rapides'
Control = TrackBar1
Track = False
Component = Circle1
ComponentProperty = 'Position.X'
CustomFormat = 'Position.X + Value*Width/Max - Owner.Circle1.Width/2'
end
end
end
Donc, effectivement, pas de code direct.
III-2-1. Revenons à la formule▲
Bien, le calcul en soi est déjà expliqué dans le source précédent (partie VCL), mais qu'est-ce que ce CustomFormat ? D'où vient ce Owner.Circle1 ? Comment fait-on pour contrôler cette formule ? Questions on ne peut plus légitimes.
III-2-2. CustomFormat▲
Je vais d'abord citer la définition faite par Embarcadero :
« LiveBindings est un framework basé sur des expressions, ce qui signifie qu'il utilise des expressions de liaison pour lier des objets à d'autres objets, ou à des champs d'ensemble de données. »
Expressions, le mot est lâché ! De fait, il y en a de deux types :
- les expressions qui vont évaluer la valeur à partir du contrôle source, en l'occurrence une propriété de ce dernier ;
- les expressions qui vont modifier la valeur entrée avant de la stocker dans le contrôle source.
Nous ne nous intéresserons qu'au premier type d'expression qui correspond à CustomFormat (pour mémoire, le second type correspond à CustomParse).
Cette expression peut contenir des calculs mais pas que ! On pourra utiliser quelques méthodes prédéfinies de chaîne telles qu'UpperCase, LowerCase, SubString, de formatage telles que Format, FormatDateTime, mais aussi de petites fonctions de test comme IfAll, IfAny, IfThen.
Bien sûr, qui dit méthodes prédéfinies dit que l'on peut aussi écrire et recenser ses propres méthodes, mais ce n'est pas le sujet de cet épisode.
III-2-3. Qui est ce Owner et pourquoi l'utiliser▲
Dans notre cas, Owner correspond à la fiche Form8. On l'utilise pour pouvoir atteindre l'objet Circle1 et donc, par la suite, sa propriété Width. Vous me rétorquerez que pourtant, on n'en a pas besoin pour les propriétés de TrackBar1. C'est exact, car la formule s'applique au propriétaire de la liaison (le contrôle source) et il n'y a donc pas besoin de préciser comment y accéder.
III-2-4. Comment faire pour vérifier la formule ?▲
C'est là qu'en général, on commence à se fâcher avec les concepteurs de cet éditeur de liens.
Je vous propose de double-cliquer sur le composant Bindingslist1. Nous obtenons alors une fenêtre listant les objets contenus par ce dernier (pour l'instant un seul),
pas très explicite hélas !
En double-cliquant à nouveau cette fois-ci sur ce lien, classé dans les « Liaisons rapides », on obtient cet écran :
On ira peut-être plus vite en choisissant l'option « Liaison des composants » située dans l'inspecteur d'objets.
Lueur d'espoir ! Il y a bien notre formule et même des boutons qui permettent d'évaluer le contrôle et la source, toutefois (et c'est ce qui fâche le plus) il est impossible de modifier la formule !
Cependant, on peut bien évaluer cette formule.
Pour les besoins de l'image écran et la vérification du calcul, j'ai modifié la position du curseur de mon Trackbar (Value = 50).
III-2-5. Comment se passer des liaisons rapides ?▲
Les détenteurs d'une version Starter procéderont de cette manière.
Beaucoup moins aisée à utiliser, c'est pourtant, dans certains cas, une solution à adopter.
Pour ce faire, je vais poser un deuxième cercle sur ma forme (Circle2), que j'ai décidé de colorer en bleu.
III-2-5-a. Première étape▲
Double-cliquez sur le composant BindingsList1(3), puis utilisez le bouton d'ajout d'un nouveau lien.
On peut aussi utiliser plus rapidement l'option « Nouveau composant LiveBinding » de l'inspecteur d'objets.
III-2-5-b. Deuxième étape ▲
Quel type de lien ? Il est vrai qu'au fil des versions, il y en a beaucoup dont certains sont même devenus obsolètes, mais gardés par souci de compatibilité ascendante.
Comme il s'agit de créer une liaison entre deux objets, j'ai choisi TBindExpression. J'aurais aussi pu choisir TBindControlValue.
III-2-5-c. Troisième étape : le remplissage des premières propriétés ▲
Encore une fois, il va falloir rester très zen et bien faire attention aux termes, car les noms de propriétés des liaisons rapides et celles que je vais exposer ici sont proches.
ControlComponent (correspond à Control d'un lien rapide) indiquera le composant dont on veut modifier une ou plusieurs propriétés. Donc, dans notre cas, le cercle bleu.
SourceComponent (correspondant donc à Component d'un lien rapide) indiquera le composant qui fournira la valeur à notre expression. Donc, le TrackBar.
Il ne faudra pas oublier d'indiquer dans quel sens va notre relation. La propriété Direction aura la valeur DirSourceToControl (valeur par défaut).
III-2-5-d. Quatrième étape : les expressions▲
On peut saisir directement l'expression déjà exposée (III.2.1 ou, et c'est la solution qui permettra de tester les formules saisies, passer par l'écran que nous avons déjà vu plus haut Comment faire pour vérifier la formule ? Donc, cliquons sur l'option « Expressions » de l'inspecteur d'objets et ajoutons notre fameuse formule. Cette fois-ci, l'expression est modifiable !
III-2-6. Que constate-t-on ?▲
Au niveau visuel, il y a une différence : un élément, indiqué par un astérisque, a été ajouté à TrackBar1.
Attention à la casse de l'expression de contrôle. Pour peu que vous la changiez, vous pourriez vous retrouver avec deux fois le même élément.
Le source de la forme, lui, s'est légèrement étoffé. Normal puisque l'on a ajouté deux éléments.
object
Form8: TForm8
Left = 0
Top = 0
Caption = 'Jeu de balle'
ClientHeight = 160
ClientWidth = 549
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object
Circle1: TCircle
Fill.Color = claRed
Position.Y = 72
.000000000000000000
Size.Width = 40
.000000000000000000
Size.Height = 50
.000000000000000000
Size.PlatformDefault = False
Stroke.Color = claRed
end
object
TrackBar1: TTrackBar
Align = Bottom
CanParentFocus = True
Orientation = Horizontal
Margins.Left = 20
.000000000000000000
Margins.Right = 20
.000000000000000000
Margins.Bottom = 10
.000000000000000000
Position.X = 20
.000000000000000000
Position.Y = 131
.000000000000000000
Size.Width = 509
.000000000000000000
Size.Height = 19
.000000000000000000
Size.PlatformDefault = False
TabOrder = 1
OnChange = TrackBar1Change
end
object
Circle2: TCircle
Fill.Color = claBlue
Position.Y = 16
.000000000000000000
Size.Width = 40
.000000000000000000
Size.Height = 50
.000000000000000000
Size.PlatformDefault = False
Stroke.Color = claBlue
end
object
BindingsList1: TBindingsList
Methods = <>
OutputConverters = <>
Left = 76
Top = 5
object
LinkControlToPropertyPositionX: TLinkControlToProperty
Category = 'Liaisons rapides'
Control = TrackBar1
Track = False
Component = Circle1
ComponentProperty = 'Position.X'
CustomFormat = 'Position.X + Value*Width/Max - Owner.Circle1.width/2'
end
object
BindExpression1: TBindExpression
Category = 'Expressions de liaison'
ControlComponent = Circle2
SourceComponent = TrackBar1
SourceExpression = 'Position.X + Value * Width/Max - Owner.Circle2.Width/2'
ControlExpression = 'Position.X'
NotifyOutputs = True
Direction = dirSourceToControl
end
end
end
Il ne nous reste plus qu'à exécuter le programme afin de tester son comportement.
Constatation : si le cercle rouge bouge correctement, le bleu lui reste fixe. Il manque donc quelque chose : le moteur des LiveBindings doit être informé qu'il faut entreprendre une action, celle qui se faisait automatiquement avec le lien rapide.
Seule solution : ajouter un bout de code à notre programme. Nous revoilà avec l'événement OnChange de notre TrackBar. Seulement, au lieu d'y indiquer le calcul, nous allons forcer l'évaluateur d'expressions à faire son boulot. Cela se fera via une instruction notifiant au moteur de traiter l'objet.
Voici donc le nouveau source du programme :
unit
UFMX_Prog1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects, Data.Bind.EngExt,
Fmx.Bind.DBEngExt, System.Rtti, System.Bindings.Outputs, Fmx.Bind.Editors,
Data.Bind.Components;
type
TForm8 = class
(TForm)
Circle1: TCircle;
TrackBar1: TTrackBar;
BindingsList1: TBindingsList;
LinkControlToPropertyPositionX: TLinkControlToProperty;
Circle2: TCircle;
BindExpression1: TBindExpression;
procedure
TrackBar1Change(Sender: TObject);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end
;
var
Form8: TForm8;
implementation
{$R *.fmx}
procedure
TForm8.TrackBar1Change(Sender: TObject);
begin
BindingsList1.Notify(Sender,''
);
end
;
end
.
Conclusion de cette partie : finalement, les liaisons rapides (quand on en a la possibilité) c'est plus simple !
III-3. Et si on appliquait ça au programme VCL ?▲
Selon le même principe, j'ajoute un cercle bleu et, fort de l'expérience sur les liaisons rapides FMX, j'ajoute les deux propriétés que je veux contrôler : Position pour le TrackBar et Left pour le cercle bleu (Shape2).
III-3-1. Lien rapide▲
Pourtant, impossible de faire une liaison rapide !* Frustrant, n'est-ce pas ? Quelle peut bien en être la cause ?
Pas de bol, je vous avais parlé en Introduction d'observabilité et TTrackBar est justement un de ces composants qui n'a aucune propriété observable. Malgré cela, nous avons pu ajouter la propriété dans le concepteur visuel : c'est vrai qu'il y a de quoi voir rouge !
Un tour dans la documentation sera le bienvenu pour essayer de comprendre. Quoique pas facile à trouver, on y découvre l'explication et la méthode pour remédier à ce problème.
Hélas, toutes les propriétés d'un contrôle ne sont pas forcément, par défaut, utilisables telles quelles avec LiveBindings (surtout s'il s'agit d'un composant VCL présent depuis longtemps).
Pour qu'il soit possible d'utiliser la propriété d'un composant de façon totalement réactive, la propriété doit avoir été rendue « observable » et le composant « réactif », c'est-à-dire que :
- la propriété voulue a été déclarée comme ObservableMember ;
- des fonctions et procédures idoines sont implémentées : CanObserve, ObserverAdded.
Mais, heureusement, cela ne veut pas dire que l'on ne peut pas utiliser une propriété non déclarée « observable » dans une expression. C'est juste que l'automatisme de liaison n'est pas effectif pour ces propriétés non déclarées.
L'objectif de cet épisode n'étant pas de créer un nouveau composant observable, chose qui pourrait faire l'objet d'un autre épisode, je vous laisse aux prises avec le tutoriel cité.
À ce stade, vous pensez que : « S'il faut réécrire les composants, autant ne pas utiliser les LiveBindings , je laisse ça à FMX ! » Toutefois l'approche manuelle, décrite au chapitre III.2.5, peut être la solution, bien que cela soit un peu contraire à l'objectif de départ : « zéro code ».
III-3-2. Lien manuel▲
Nous allons donc faire la même chose que dans le chapitre III.2.5.
Première étape, indispensable, il faut poser sur la forme un TBindingsList (en FMX, la création du lien rapide l'avait généré automatiquement). On profitera de l'éditeur de liaison * pour ôter les deux propriétés que nous avions mises au chapitre précédent, car elles sont devenues inutiles.
Deuxième étape, il faut ajouter une expression (BindExpression) et remplir les différentes propriétés.
Troisième étape, il s'agit de notifier, par programme, au moteur qu'il doit prendre en compte la modification de valeur, avec la même instruction que dans le chapitre déjà cité.
Voici, synthétiquement, la nouvelle présentation* dans l'EDI.
Le source modifié
Au passage, notez l'ajout de plusieurs unités, dont les RTTI. Retour à la note de bas de page .
unit
U_Prog1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.ComCtrls,
Data.Bind.EngExt, Vcl.Bind.DBEngExt, System.Rtti, System.Bindings.Outputs,
Vcl.Bind.Editors, Data.Bind.Components;
type
TForm8 = class
(TForm)
TrackBar1: TTrackBar;
Shape1: TShape;
Shape2: TShape;
BindingsList1: TBindingsList;
BindExpression1: TBindExpression;
procedure
TrackBar1Change(Sender: TObject);
procedure
Edit1KeyPress(Sender: TObject; var
Key: Char
);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end
;
var
Form8: TForm8;
implementation
{$R *.dfm}
procedure
TForm8.Edit1KeyPress(Sender: TObject; var
Key: Char
);
begin
end
;
procedure
TForm8.TrackBar1Change(Sender: TObject);
var
percent : Double
;
posCurseur: integer
;
begin
// Méthode "Classique", Calcul décomposé pour les besoins de l'explication
// calcul du pourcentage sur la barre
Percent:=TrackBar1.Position / TrackBar1.Max;
// Calcul en pixels, Arrondi nécessaire
PosCurseur:=Round(TrackBar1.Width*Percent);
// Positionnement exact du cercle rouge
Shape1.Left:=TrackBar1.Left+posCurseur-(Shape1.Width div
2
);
// Méthode via les LiveBindings
// notification d'un changement au "moteur" pour déplacer le cercle bleu
BindingsList1.Notify(Sender,''
);
end
;
end
.
Et voici son DFM associé :
object
Form8: TForm8
Left = 0
Top = 0
Caption = 'D'#233'placer la balle'
ClientHeight = 193
ClientWidth = 447
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object
Shape1: TShape
Left = 0
Top = 80
Width = 40
Height = 41
Brush.Color = clRed
Pen.Color = clRed
Shape = stCircle
end
object
Shape2: TShape
Left = 0
Top = 8
Width = 40
Height = 41
Brush.Color = clBlue
Pen.Color = clBlue
Shape = stCircle
end
object
TrackBar1: TTrackBar
AlignWithMargins = True
Left = 20
Top = 145
Width = 407
Height = 45
Margins.Left = 20
Margins.Right = 20
Align = alBottom
TabOrder = 0
OnChange = TrackBar1Change
end
object
BindingsList1: TBindingsList
Methods = <>
OutputConverters = <>
Left = 72
Top = 16
object
BindExpression1: TBindExpression
Category = 'Expressions de liaison'
ControlComponent = Shape2
SourceComponent = TrackBar1
SourceExpression = 'Left+ Position * Width / Max - Owner.Shape2.Width/2'
ControlExpression = 'Left'
NotifyOutputs = False
Direction = dirSourceToControl
end
end
end
L'exécution du programme est conforme à l'attente.
IV. Conclusion de cet épisode▲
Oui, je le concède volontiers, ce n'est pas forcément concluant :
- on ne comprend pas trop à quoi cela pourrait bien servir en VCL, surtout que les composants ne sont pas tous observables (il n'y a d'ailleurs, à ma connaissance, pas de liste de ceux qui le sont) ;
- en FMX, il faut se faire une raison, les LiveBindings semblent incontournables (surtout s'il s'agit d'utilisation de sources de données), mais il y a des moments de frustration (c'est le moins que l'on puisse écrire).
Pour contrebalancer cela, cette introduction n'a pas abordé les liaisons avec des objets plus complexes ou des bases de données. De nombreux tutoriels ou vidéos existent déjà qui sont certainement plus alléchants (au niveau des possibilités) que cette introduction.
Mais je compte bien écrire d'autres épisodes et aborder ces questions !
Tous mes remerciements à Gilles (gvasseur58) et Jean-Luc (Alcatîz) pour leur relecture et conseils techniques et à Claude (ClaudeLeloup) pour ses corrections orthographiques et grammaticales.
V. Notes▲
Les programmes proposés ont été écrits avec la dernière version en date de publication, c'est-à-dire la version Delphi 10.2 Tokyo, pour être précis avec la version Entreprise. Néanmoins, ils sont réalisables avec la version Starter du produit, voire des versions plus anciennes.