Comment personnaliser le DBNavigator

"D'accord, le DBNavigator fait son travail de navigation dans les données et de gestion des enregistrements. Malheureusement, mes clients veulent une expérience plus conviviale, comme des graphiques de boutons personnalisés et des légendes,…"

Cette demande est venue d'un développeur Delphi cherchant un moyen d'améliorer la puissance du composant DBNavigator. 

Le DBNavigator est un excellent composant - il fournit une interface de type magnétoscope pour naviguer dans les données et gérer les enregistrements dans les applications de base de données. La navigation dans les enregistrements est assurée par les boutons Premier, Suivant, Précédent et Dernier. La gestion des enregistrements est assurée par les boutons Modifier, Publier, Annuler, Supprimer, Insérer et Actualiser. Delphi fournit en un seul composant tout ce dont vous avez besoin pour opérer sur vos données.

Cependant, comme l’a également déclaré l’auteur de l’enquête par e-mail, le DBNavigator ne dispose pas de certaines fonctionnalités telles que des glyphes personnalisés, des légendes de boutons, etc..

Un DBNavigator plus puissant

De nombreux composants Delphi ont des propriétés et des méthodes utiles qui sont marquées invisibles ("protégées") pour un développeur Delphi. Si tout va bien, pour accéder à de tels membres protégés d'un composant, une technique simple appelée le "hack protégé" peut être utilisée.

Tout d'abord, vous ajouterez une légende à chaque bouton DBNavigator, puis vous ajouterez des graphiques personnalisés, et enfin, vous activerez OnMouseUp pour chaque bouton. 

Du DBNavigator "ennuyeux" à l'un des:

  • Graphiques standard et légendes personnalisées
  • Légendes uniquement
  • Graphiques personnalisés et légendes personnalisées

Let's Rock 'n' Roll

Le DBNavigator a une propriété Buttons protégée. Ce membre est un tableau de TNavButton, un descendant de TSpeedButton. 

Étant donné que chaque bouton de cette propriété protégée hérite de TSpeedButton, si vous mettez la main dessus, vous pourrez travailler avec des propriétés TSpeedButton "standard" comme: Caption (une chaîne qui identifie le contrôle pour l'utilisateur), Glyph (le bitmap qui apparaît sur le bouton), Disposition (détermine où l'image ou le texte apparaît sur le bouton)…

À partir de l'unité DBCtrls (où DBNavigator est défini), vous "lisez" que la propriété Buttons protégée est déclarée comme:

Boutons: tableau[TNavigateBtn] de TNavButton;

Où TNavButton hérite de TSpeedButton et TNavigateBtn est une énumération, définie comme:

TNavigateBtn =
(nbFirst, nbPrior, nbNext, nbLast, nbInsert,
nbDelete, nbEdit, nbPost, nbCancel, nbRefresh);

Notez que TNavigateBtn contient 10 valeurs, chacune identifiant un bouton différent sur un objet TDBNavigator. Voyons maintenant comment pirater un DBNavigator:

DBNavigator amélioré

Tout d'abord, configurez un formulaire Delphi simple d'édition de données en plaçant au moins un DBNavigator, un DBGrid, un DataSoure et un objet Dataset de votre choix (ADO, BDE, dbExpres,…). Assurez-vous que tous les composants sont "connectés".

Deuxièmement, piratez un DBNavigator en définissant une classe "factice" héritée, au-dessus de la déclaration Form, comme:

type THackDBNavigator = classe(TDBNavigator);
type
TForm1 = classe(TForm)

Ensuite, pour pouvoir afficher des légendes et des graphiques personnalisés sur chaque bouton DBNavigator, vous devrez configurer des glyphes. Vous pouvez utiliser le composant TImageList et attribuer 10 images (.bmp ou .ico), chacune représentant une action d'un bouton particulier d'un DBNavigator.

Troisièmement, dans l'événement OnCreate pour Form1, ajoutez un appel comme:

procédure TForm1.FormCreate (expéditeur: TObject);
SetupHackedNavigator (DBNavigator1, ImageList1);
fin;

Assurez-vous d'ajouter la déclaration de cette procédure dans la partie privée de la déclaration de formulaire, comme:

type
TForm1 = classe(TForm)

procédure privée SetupHackedNavigator (const Navigateur: TDBNavigator;
const Glyphes: TImageList);

Quatrièmement, ajoutez la procédure SetupHackedNavigator. La procédure SetupHackedNavigator ajoute des graphiques personnalisés à chaque bouton et attribue une légende personnalisée à chaque bouton.

les usages Boutons; // !!! n'oublie pas
procédure TForm1.SetupHackedNavigator
(const Navigateur: TDBNavigator;
const Glyphes: TImageList);
const
Légendes: tableau[TNavigateBtn] de chaîne =
(«Initial», «Précédent», «Plus tard», «Final», «Ajouter»,
'Effacer', 'Corriger', 'Envoyer', 'Retirer', 'Revivre');
(*
Légendes: tableau [TNavigateBtn] de chaîne =
('Premier', 'Avant', 'Suivant', 'Dernier', 'Insérer',
'Supprimer', 'Modifier', 'Publier', 'Annuler', 'Actualiser');

en Croatie (localisé):
Légendes: tableau [TNavigateBtn] de chaîne =
(«Prvi», «Prethodni», «Slijedeci», «Zadnji», «Dodaj»,
«Obrisi», «Promjeni», «Spremi», «Odustani», «Osvjezi»);
*)
var
btn: TNavigateBtn;
commencer pour btn: = faible (TNavigateBtn) à Élevé (TNavigateBtn) faire avec THackDBNavigator (Navigateur) .Boutons [btn] dobegin// à partir du tableau Const légendes
Légende: = Légendes [btn];
// le nombre d'images dans la propriété Glyph
NumGlyphs: = 1;
// Supprimer l'ancien glyphe.
Glyphe: = néant;
// Attribuer le personnalisé
Glyphs.GetBitmap (Entier (btn), Glyphe);
// gylphe au-dessus du texte
Disposition: = blGlyphTop;
// expliqué plus tard
OnMouseUp: = HackNavMouseUp;
fin;
fin; (* SetupHackedNavigator *)

Ok, expliquons. Vous parcourez tous les boutons du DBNavigator. Rappelez-vous que chaque bouton est accessible à partir de la propriété du tableau Buttons protégé, d'où la nécessité de la classe THackDBNavigator. Le type du tableau Buttons étant TNavigateBtn, vous passez du bouton "premier" (en utilisant la fonction Low) au bouton "dernier" (en utilisant la fonction High). Pour chaque bouton, vous supprimez simplement l '"ancien" glyphe, attribuez le nouveau (à partir du paramètre Glyphs), ajoutez la légende du tableau Légendes et marquez la disposition du glyphe.

Notez que vous pouvez contrôler les boutons affichés par un DBNavigator (pas celui piraté) via sa propriété VisibleButtons. Une autre propriété dont vous voudrez peut-être modifier la valeur par défaut est Hints-use it pour fournir des conseils d'aide de votre choix pour le bouton de navigateur individuel. Vous pouvez contrôler l'affichage des conseils en modifiant la propriété ShowHints.

C'est ça. Voilà pourquoi vous avez choisi Delphi!

donne m'en plus!

Pourquoi arrêter ici? Vous savez que lorsque vous cliquez sur le bouton «nbNext», la position actuelle de l'ensemble de données est avancée à l'enregistrement suivant. Que se passe-t-il si vous voulez déplacer, disons, 5 enregistrements à l'avance si l'utilisateur maintient la touche CTRL tout en appuyant sur le bouton? Et ça? 

Le DBNavigator «standard» n'a pas l'événement OnMouseUp - celui qui porte le paramètre Shift du TShiftState - vous permettant de tester l'état des touches Alt, Ctrl et Shift. Le DBNavigator fournit uniquement l'événement OnClick que vous pouvez gérer. 

Cependant, le THackDBNavigator peut simplement exposer l'événement OnMouseUp et vous permettre de "voir" l'état des touches de contrôle et même la position du curseur au-dessus du bouton particulier lorsque vous cliquez dessus.!

Ctrl + clic: = 5 rangées devant

Pour exposer OnMouseUp, vous affectez simplement votre procédure de gestion d'événements personnalisée à l'événement OnMouseUp pour le bouton du DBNavigator piraté. Ceci est déjà fait exactement dans la procédure SetupHackedNavigator:
OnMouseUp: = HackNavMouseUp;

Maintenant, la procédure HackNavMouseUp pourrait ressembler à:

procédure TForm1.HackNavMouseUp
(Expéditeur: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Entier);
const MoveBy: entier = 5;
beginif NE PAS (L'expéditeur est TNavButton) ensuite Sortie;
Cas TNavButton (expéditeur) .Index de
nbPrior:
si (ssCtrl dans Shift) ensuite
TDBNavigator (TNavButton (Sender) .Parent).
DataSource.DataSet.MoveBy (-MoveBy);
nbSuivant:
si (ssCtrl dans Shift) ensuite
TDBNavigator (TNavButton (Sender) .Parent).
DataSource.DataSet.MoveBy (MoveBy);
fin;
fin; (* HackNavMouseUp *)

Notez que vous devez ajouter la signature de la procédure HackNavMouseUp dans la partie privée de la déclaration de formulaire (près de la déclaration de la procédure SetupHackedNavigator):

type
TForm1 = classe(TForm)

procédure privée SetupHackedNavigator (const Navigateur: TDBNavigator;
const Glyphes: TImageList);
procédure HackNavMouseUp (expéditeur: TObject; bouton: TMouseButton;
Shift: TShiftState; X, Y: Entier);

Ok, expliquons encore une fois. La procédure HackNavMouseUp gère l'événement OnMouseUp pour chaque bouton DBNavigator. Si l'utilisateur maintient la touche CTRL tout en cliquant sur le bouton nbNext, l'enregistrement en cours pour l'ensemble de données lié est déplacé "MoveBy" (défini comme constant avec la valeur de 5) enregistrements en avance.

Quelle? Trop compliqué?

Oui. Vous n'avez pas besoin de jouer avec tout cela si vous avez seulement besoin de vérifier l'état des touches de contrôle lorsque vous avez cliqué sur le bouton. Voici comment faire de même dans l'événement OnClick "ordinaire" du DBNavigator "ordinaire":

procédure TForm1.DBNavigator1Click
(Expéditeur: TObject; bouton: TNavigateBtn);
une fonction CtrlDown: booléen;
var
État: TKeyboardState;
commencer
GetKeyboardState (State);
Résultat: = ((State [vk_Control] And 128) 0);
fin;
const MoveBy: entier = 5;
casse Bouton de
nbPrior:
si CtrlDown ensuite
DBNavigator1.DataSource.DataSet.MoveBy (-MoveBy);
nbSuivant:
si CtrlDown ensuite
DBNavigator1.DataSource.DataSet.MoveBy (MoveBy);
fin; //Cas
fin; (* DBNavigator2Click *)

C'est tout le monde

Et enfin, le projet est terminé. Ou vous pouvez continuer. Voici un scénario / tâche / idée pour vous: 

Supposons qu'un seul bouton remplace les boutons nbFirst, nbPrevious, nbNext et nbLast. Vous pouvez utiliser les paramètres X et Y dans la procédure HackNavMouseUp pour trouver la position du curseur lorsque le bouton a été relâché. Maintenant, à ce seul bouton ("pour les gouverner tous"), vous pouvez attacher une image qui a 4 zones, chaque zone est supposée imiter l'un des boutons que vous remplacez ...?