Tutoriel : Création de listes de collections avec LiveBindings

De RAD Studio
Aller à : navigation, rechercher

Remonter à Tutoriels Bases de données et LiveBindings


Ce tutoriel montre comment construire l'application utilisée dans le projet exemple ListCollections.

Remarque : Vous pouvez trouver le projet exemple ListCollections sur :

Démarrer | Programmes | Embarcadero RAD Studio Sydney | Exemples puis naviguez jusqu'à Object Pascal\FireMonkey Desktop\ListCollections.


Cet exemple est décrit dans Exemple FMX.ListCollections.

Etape 1 : Création du projet

  1. Créez un nouveau projet : Fichier > Nouveau > Application multi-périphérique - Delphi.
    Dans l'expert, choisissez Application vide.
  2. Sélectionnez la fiche, et changez sa propriété Caption dans l'inspecteur d'objets en "List Collections Demo".
  3. Ajoutez un composant TLabel à la fiche, et changez sa propriété Text dans l'inspecteur d'objets en "Collection: ".
  4. Dans la palette d'outils, localisez un composant ComboBox et déposez-le sur la fiche.
  5. Dans le Concepteur de fiches, cliquez avec le bouton droit sur le composant ComboBox1 et sélectionnez Ajouter un élément > TListBoxItem.
    AddItem.png
  6. Ajoutez quatre composants TLabel à la fiche, et changez la propriété Text pour les composants respectifs en :
    "Control Component:", "Control Expression:", "Source Component:", "Source Expression:"
    Changez également la propriété Name en :
    "LabelControlComponent", "LabelControlExpression", "LabelSourceComponent"
  7. Pour chaque libellé ("LabelControlComponent", "LabelControlExpression", "LabelSourceComponent"), ajoutez un composant TEdit, et changez la propriété Name respectivement en :
    "EditControlComponent", "EditControlExpression", "EditSourceComponent"
    De même, pour chaque TEdit, définissez la propriété Enabled sur False.
  8. Ajoutez un composant TEdit à la fiche, et changez la propriété Name en "EditSourceExpression".
  9. Ajoutez deux composants TButton à la fiche, et changez la propriété Text respectivement en "Fill" et "Clear".
    . Changez également la propriété Name respectivement en "ButtonEvaluate" et "ButtonClear".
  10. Ajoutez trois composants TCheckBox à la fiche, et changez la propriété Text respectivement en :
    "Auto Active", "Active", "Auto Fill"
    Changez également la propriété Name respectivement en :
    "CheckBoxAutoActive", "CheckBoxActive", "CheckBoxAutoFill"
    LabelAndEdit.png
  11. Dans la palette d'outils, localisez un composant TListBox et déposez-le sur la fiche.
  12. Ajoutez un composant TBindingList sur la fiche.
  13. Sur la fiche, cliquez avec le bouton droit sur le composant BindingList1 et sélectionnez Liaison des composants...
  14. Dans l'éditeur de listes de liaisons, sélectionnez Nouvelle liaison (Ins).
    NewBinding.png
  15. Dans la boîte de dialogue Nouveau LiveBinding, sélectionnez Listes > TBindList.
  16. Dans l'inspecteur d'objets, définissez la propriété Control Component sur ListBox1.
    ControlComponent.png

Etape 2 : Implémentation

  • L'unité SampleCollections.pas implémente les collections d'éléments supplémentaires supportées qui seront exportées dans la zone de liste par le biais de LiveBindings. L'exemple utilise un pattern de conception de fabrique de classe pour construire dynamiquement différents types de collections :
  • Un dictionnaire de données
  • Une liste d'objets
  • Une liste de génériques
  • Une liste de chaînes
  • L'exemple ListCollections n'est pas approprié aux débutants (une connaissance avancée est nécessaire ; pour lire le code, vous devez bien connaître RTTI, et les éléments de langage avancés tels que les méthodes anonymes et les patterns de conception).


Ajoutez l'unité SampleCollections.pas au projet.

Dans la section private de la classe TForm1, ajoutez ces variables :

Delphi :
FChecking: Boolean;
FDataObjects: TDictionary<TCollectionFactory, TObject>;
FFactory: TCollectionFactory;
FChanging: Boolean;

Ajoutez la variable d'unité :

Delphi :
var
  BindScope1: TBindScope;

1. Ajouter un gestionnaire d'événement OnCreate de fiche

1. Dans la vue Structure, sélectionnez le composant Form1.
2. Dans l'inspecteur d'objets, ouvrez l'onglet Evénements, puis double-cliquez sur OnCreate.
3. Dans l'éditeur de code, ajoutez le code suivant :
Delphi :
procedure TForm1.FormCreate(Sender: TObject);
var
  LFactory: TCollectionFactory;
  LListItem: TListBoxItem;
begin
  BindScope1 := TBindScope.Create(Self);
  BindList1.SourceComponent := BindScope1;
  FDataObjects := TObjectDictionary<TCollectionFactory, TObject>.Create([doOwnsValues]);
  // List test data in combobox
  for LFactory in GetCollectionFactories do
  begin
    LListItem := TListBoxItem.Create(ComboBox1);
    ComboBox1.AddObject(LListItem);
    LListItem.Text := LFactory.DisplayName;
    LListItem.Data := LFactory;
  end;
  Application.OnIdle := OnIdle;
  UpdateDisplayFields;
end;

Dans la section public de la classe TForm1, ajoutez ces procédures :

Delphi :
procedure OnIdle(Sender: TObject; var Done: Boolean);;
procedure UpdateDisplayFields;


Implémentation pour les procédures ci-dessus :

Delphi :
procedure TForm1.OnIdle(Sender: TObject; var Done: Boolean);
begin
  FChecking := True;
  try
    CheckBoxActive.IsChecked := BindList1.Active;
    CheckBoxAutoFill.IsChecked := BindList1.AutoFill;
    CheckBoxAutoActivate.IsChecked := BindList1.AutoActivate;
  finally
    FChecking := False;
  end;
end;

//  Display information about binding
procedure TForm1.UpdateDisplayFields;
var
  LSourceExpression: string;
  LControlExpression: string;
  LSourceComponent: string;
  LControlComponent: string;
begin
  if BindList1.FormatExpressions.Count > 0 then
  begin
    LSourceExpression := BindList1.FormatExpressions[0].SourceExpression;
    LControlExpression := BindList1.FormatExpressions[0].ControlExpression;
  end;
  if BindList1.ControlComponent <> nil then
    LControlComponent := BindList1.ControlComponent.ClassName;
  if BindList1.SourceComponent <> nil then
  begin
    LSourceComponent := BindList1.SourceComponent.ClassName;
    if BindList1.SourceComponent is TBindScope then
      with TBindScope(BindList1.SourceComponent) do
        if DataObject <> nil then
          LSourceComponent := LSourceComponent + ' (' +
            DataObject.ClassName + ')'
      else if Component <> nil then
        LSourceComponent := LSourceComponent + ' (' +
          Component.ClassName + ')';
  end;
  EditSourceExpression.Text := LSourceExpression;
  EditControlExpression.Text := LControlExpression;
  EditControlComponent.Text := LControlComponent;
  EditSourceComponent.Text := LSourceComponent;
end;

2. Ajouter un gestionnaire d'événement OnChange de zone de liste déroulante

1. Sélectionnez dans la vue Structure le composant ComboBox1.
2. Dans l'inspecteur d'objets, ouvrez l'onglet Evénements, puis double-cliquez sur OnChange.
3. Dans l'éditeur de code, ajoutez le code suivant :
Delphi :
procedure TForm1.ComboBox1Change(Sender: TObject);
var
  LDataObject: TObject;
begin
  FChanging := True;
  try
    if ComboBox1.ItemIndex <> -1 then
    begin
      FFactory := ComboBox1.ListBox.Selected.Data as TCollectionFactory;
    end
    else
    begin
      FFactory := nil;
    end;
    if FFactory <> nil then
    begin
      if BindList1.FormatExpressions.Count = 0 then
        BindList1.FormatExpressions.Add;
      BindList1.FormatExpressions[0].SourceExpression := FFactory.GetExpression;
      BindList1.FormatExpressions[0].ControlExpression := 'Text';
      LDataObject := FFactory.CreateCollection;
      FDataObjects.AddOrSetValue(FFactory, LDataObject);  // Track objects in order to free when not in use
      // Set DataObject last because this can trigger activation and auto fill
      BindScope1.DataObject := LDataObject;
    end
    else
      BindScope1.DataObject := nil;
  finally
    FChanging := False;
    UpdateDisplayFields;
  end;
end;

3. Ajouter un gestionnaire d'événement OnClick de bouton

1. Dans le volet Structure, sélectionnez le composant ButtonEvaluate.
2. Dans l'inspecteur d'objets, ouvrez l'onglet Evénements, puis double-cliquez sur OnClick.
3. Dans l'éditeur de code, ajoutez le code suivant :
Delphi :
procedure TForm1.ButtonEvaluateClick(Sender: TObject);
begin
  BindList1Activating(Self); // Update expression
  BindList1.FillList;
end;
4. Répétez les étapes ci-dessus pour ButtonClear, en ajoutant le code suivant dans l'éditeur de code :
Delphi :
procedure TForm1.ButtonClearClick(Sender: TObject);
begin
  BindList1.ClearList;
end;

4. Ajouter un gestionnaire d'événement OnChange de case à cocher

1. Sélectionnez le composant CheckBoxAutoActive dans la vue Structure.
2. Dans l'inspecteur d'objets, ouvrez l'onglet Evénements, puis double-cliquez sur OnChange.
3. Dans l'éditeur de code, ajoutez le code suivant :
Delphi :
procedure TForm1.CheckBoxAutoActivateChange(Sender: TObject);
begin
  if not FChecking then
    BindList1.AutoActivate := CheckBoxAutoActivate.IsChecked;
end;
4. Répétez les étapes ci-dessus pour CheckBoxActive et CheckBoxAutoFill, en ajoutant le code suivant dans l'éditeur de code :
Delphi :
procedure TForm1.CheckBoxActiveChange(Sender: TObject);
begin
  if not FChecking then
    BindList1.Active := CheckBoxActive.IsChecked;
end;
Delphi :
procedure TForm1.CheckBoxAutoFillChange(Sender: TObject);
begin
  if not FChecking then
    BindList1.AutoFill := CheckBoxAutoFill.IsChecked;
end;

5. Ajouter les gestionnaires d'événement OnActivating et OnEvalError de liste de liaisons

1. Sélectionnez le composant BindList1 dans la vue Structure.
2. Dans l'inspecteur d'objets, ouvrez l'onglet Evénements, puis double-cliquez sur OnActivating.
3. Dans l'éditeur de code, ajoutez le code suivant :
Delphi :
procedure TForm1.BindList1Activating(Sender: TObject);
begin
  if not FChanging then
    if BindList1.FormatExpressions.Count > 0 then
      BindList1.FormatExpressions[0].SourceExpression := EditSourceExpression.Text;
end;
4. Dans l'inspecteur d'objets, ouvrez l'onglet Evénements, puis double-cliquez sur OnEvalError.
5. Dans l'éditeur de code, ajoutez le code suivant :
Delphi :
procedure TForm1.BindList1EvalError(Sender: TObject; AException: Exception);
begin
  // Generate a new exception with more information
  raise TBindCompException.CreateFmt(
    'Evaluation Exception'#13#10 +
    'Component Name: %s'#13#10 +
    'Exception Class: %s'#13#10 +
    'Exception Message: %s',
    [TComponent(Sender).Name, AException.ClassName, AException.Message]);
end;

Les résultats

Appuyez sur F9 ou choisissez Exécuter > Exécuter.

Classes

List Collections Demo représente la fenêtre principale de l'exemple. Elle contient les composants suivants :

Utilisations

Voir aussi