Opprette og tilpasse knapper med DBNavigator

"Ok, DBNavigator gjør jobben sin med å navigere i data og administrere poster. Dessverre ønsker kundene mine mer brukervennlig opplevelse, som tilpasset knappegrafikk og bildetekst,... "

Denne henvendelsen kom fra a Delphi-utvikler søker etter en måte å forbedre kraften til DBNavigator-komponenten.

DBNavigator er en flott komponent - den gir et videospillerlignende grensesnitt for å navigere i data og administrere poster i databaseapplikasjoner. Record navigation er gitt av knappene Først, Neste, Før og Siste. Record management er levert av knappene Rediger, Post, Avbryt, Slett, Sett inn og Oppdater. I en komponent gir Delphi alt du trenger, for å bruke dataene dine.

Som forfatteren av e-posthenvendelsen også uttalte, mangler DBNavigator noen funksjoner som tilpassede glyfer, knappetekster og andre.

En kraftigere DBNavigator

Mange Delphi-komponenter har nyttige egenskaper og metoder som er merket usynlige ("beskyttet") for en Delphi-utvikler. For å forhåpentligvis få tilgang til slike beskyttede medlemmer av en komponent, kan en enkel teknikk kalt "beskyttet hack" brukes.

instagram viewer

Først legger du til en bildetekst til hver DBNavigator-knapp, deretter legger du til tilpasset grafikk, og til slutt vil du OnMouseUp-aktivere hver knapp.

Fra den "kjedelige" DBNavigatoren til en av:

  • Standard grafikk og tilpassede bildetekster
  • Bare bildetekster
  • Tilpasset grafikk og tilpassede bildetekster

La oss rocke 'n' roll

DBNavigator har en beskyttet knapp-eiendom. Dette medlemmet er et utvalg av TNavButton, en etterkommer av TSpeedButton.

Siden hver knapp i denne beskyttede eiendommen arver fra TSpeedButton, vil du kunne jobbe med "standard" TSpeedButton-egenskaper som: hvis du får tak i det. Bildetekst (en streng som identifiserer kontrollen til brukeren), Glyph (bitmappen som vises på knappen), Layout (bestemmer hvor bildet eller teksten skal vises på knapp)...

Fra DBCtrls-enheten (der DBNavigator er definert) "leser" du at den beskyttede knappene-eiendommen er erklært som:

knapper: matrise[TNavigateBtn] av TNavButton;

Hvor TNavButton arver fra TSpeedButton og TNavigateBtn er en oppregning, definert som:

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

Merk at TNavigateBtn har 10 verdier, som hver identifiserer en annen knapp på et TDBNavigator-objekt. La oss se hvordan du hacker en DBNavigator:

Forbedret DBNavigator

Først må du sette opp en enkel dataredigerende Delphi-skjema ved å plassere minst en DBNavigator, a DBGrid, en DataSoure og en Datasettobjekt etter ditt valg (ADO, BDE, dbExpres, ...). Forsikre deg om at alle komponentene er "tilkoblet".

For det andre, hack en DBNavigator ved å definere en arvet "dummy" -klasse, over skjemaerklæringen, som:

type THackDBNavigator = klasse(TDBNavigator);
type
TForm1 = klasse(TForm)
...

For å kunne vise egendefinerte bildetekster og grafikk på hver DBNavigator-knapp, må du konfigurere noen symboler. Du kan bruke TImageList-komponenten og tilordne 10 bilder (.bmp eller .ico), som hver representerer en handling av en bestemt knapp på en DBNavigator.

For det tredje, i OnCreate-arrangement for skjema1, legg til en samtale som:

fremgangsmåte TForm1.FormCreate (avsender: TObject);
SetupHackedNavigator (DBNavigator1, ImageList1);
slutt;

Sørg for at du legger til erklæringen for denne prosedyren i den private delen av skjemaerklæringen, som:

type
TForm1 = klasse(TForm)
...
privateprocedure SetupHackedNavigator (konst Navigator: TDBNavigator;
konst Glyphs: TImageList);
...

For det fjerde, legg til SetupHackedNavigator-prosedyren. SetupHackedNavigator-prosedyren legger til tilpasset grafikk til hver knapp og tildeler en tilpasset bildetekst til hver knapp.

bruker knapper; //!!! ikke glem
fremgangsmåte TForm1.SetupHackedNavigator
(konst Navigator: TDBNavigator;
konst Glyphs: TImageList);
konst
Bildetekster: matrise[TNavigateBtn] av streng =
('Innledende', 'Forrige', 'Senere', 'Endelig', 'Legg til',
'Slett', 'Rett', 'Send', 'Tilbaketrekning', 'Gjenoppliv');
(*
Bildetekster: matrise [TNavigateBtn] of string =
('Først', 'Før', 'Neste', 'Siste', 'Sett inn',
'Delete', 'Edit', 'Post', 'Cancel', 'Refresh');

i Kroatia (lokalisert):
Bildetekster: matrise [TNavigateBtn] of string =
('Prvi', 'Prethodni', 'Slijedeci', 'Zadnji', 'Dodaj',
'Obrisi', 'Promjeni', 'Spremi', 'Odustani', 'Osvjezi');
*)
Var
btn: TNavigateBtn;
beginfor btn: = Lav (TNavigateBtn) til Høy (TNavigateBtn) gjøre med THackDBNavigator (Navigator) .Knapper [btn] dobegin// fra billedtekstens konst-matrise
Bildetekst: = Bildetekst [btn];
// antall bilder i Glyph-egenskapen
NumGlyphs: = 1;
// Fjern den gamle glyfen.
Glyph: = nil;
// Tildel den tilpassede
Glyphs. GetBitmap (heltall (btn), Glyph);
// gylf over teksten
Layout: = blGlyphTop;
// forklart senere
OnMouseUp: = HackNavMouseUp;
slutt;
slutt; (* SetupHackedNavigator *)

OK, la oss forklare. Du itererer gjennom alle knappene i DBNavigator. Husk at hver knapp er tilgjengelig fra den beskyttede knappen-array-egenskapen - derfor behovet for THackDBNavigator-klassen. Siden typen av knapper er TNavigateBtn, går du fra den "første" (bruker Lav funksjon) -knappen til "siste" (ved å bruke Høy funksjon) en. For hver knapp fjerner du ganske enkelt den "gamle" glyphen, tilordner den nye (fra Glyphs-parameteren), legger til bildeteksten fra bildetekstgruppen og markerer utformingen av glyphen.

Merk at du kan kontrollere hvilke knapper som vises av en DBNavigator (ikke den hacket) gjennom egenskapen VisibleButtons. En annen egenskap hvis standardverdi du kanskje vil endre er Hints - bruk den til å levere Hjelpetips du velger for den enkelte navigatorknappen. Du kan kontrollere visningen av hintene ved å redigere ShowHints-egenskapen.

Det er det. Dette er grunnen til at du har valgt Delphi!

Gi meg mer!

Hvorfor stoppe her? Du vet at når du klikker på 'nbNeste' -knappen, blir datasettens nåværende posisjon avansert til neste post. Hva om du vil flytte, la oss si, 5 poster fremover hvis brukeren holder CTRL-tasten mens han trykker på knappen? Hva med det?

Den "standard" DBNavigatoren har ikke OnMouseUp-hendelsen - den som har Shift-parameteren til TShiftState - slik at du kan teste tilstanden til Alt-, Ctrl- og Shift-tastene. DBNavigator tilbyr bare OnClick-hendelsen du kan håndtere.

THackDBNavigator kan imidlertid bare eksponere OnMouseUp-hendelsen og gjøre det mulig for deg å "se" statusen til kontrolltastene og til og med plasseringen av markøren over den aktuelle knappen når du klikker!

Ctrl + Klikk: = 5 rader foran

For å avsløre OnMouseUp tilordner du bare den tilpassede hendelseshåndteringsprosedyren til OnMouseUp-hendelsen for knappen til den hacket DBNavigator. Dette er allerede gjort i SetupHackedNavigator-prosedyren:
OnMouseUp: = HackNavMouseUp;

Nå kan prosedyren HackNavMouseUp se ut:

fremgangsmåte TForm1.HackNavMouseUp
(Avsender: TObject; Knapp: TMouseButton;
Skift: TShiftState; X, Y: Heltall);
konst MoveBy: heltall = 5;
beginifIKKE (Avsender er TNavButton) deretter Exit;
sak TNavButton (avsender). Indeks av
nbPrior:
hvis (ssCtrl i Shift) deretter
TDBNavigator (TNavButton (avsender). Foreldre).
Datakilde. Datasett. MoveBy (-MoveBy);
nbNext:
hvis (ssCtrl i Shift) deretter
TDBNavigator (TNavButton (avsender). Foreldre).
Datakilde. Datasett. MoveBy (MoveBy);
slutt;
slutt; (* HackNavMouseUp *)

Merk at du må legge til signaturen til HackNavMouseUp-prosedyren i den private delen av skjemadeklarasjonen (nær erklæringen for SetupHackedNavigator-prosedyren):

type
TForm1 = klasse(TForm)
...
privateprocedure SetupHackedNavigator (konst Navigator: TDBNavigator;
konst Glyphs: TImageList);
fremgangsmåte HackNavMouseUp (avsender: TObject; Knapp: TMouseButton;
Skift: TShiftState; X, Y: Heltall);
...

OK, la oss forklare, en gang til. HackNavMouseUp-prosedyren håndterer OnMouseUp-hendelsen for hver DBNavigator-knapp. Hvis brukeren holder CTRL-tasten mens han klikker på nbNeste-knappen, flyttes den gjeldende posten for det koblede datasettet "MoveBy" (definert som konstant med verdien på 5) poster fremover.

Hva? Overcomplicated?

Jepp. Du trenger ikke rote med alt dette hvis du bare trenger å sjekke tilstanden til kontrolltastene når knappen ble klikket. Slik gjør du det samme på det "vanlige" OnClick-hendelse av den "vanlige" DBNavigatoren:

fremgangsmåte TForm1.DBNavigator1Click
(Avsender: TObject; Knapp: TNavigateBtn);
funksjon CtrlDown: Boolean;
Var
Oppgi: TKeyboardState;
begynne
GetKeyboardState (stat);
Resultat: = ((Oppgi [vk_Control] Og 128) 0);
slutt;
konst MoveBy: heltall = 5;
begincase Knapp av
nbPrior:
hvis CtrlDown deretter
DBNavigator1.DataSource. Datasett. MoveBy (-MoveBy);
nbNext:
hvis CtrlDown deretter
DBNavigator1.DataSource. Datasett. MoveBy (MoveBy);
slutt; //case
slutt; (* DBNavigator2Click *)

Det var alt folkens

Og til slutt er prosjektet ferdig. Eller du kan fortsette. Her er et scenario / oppgave / idé for deg:

La oss si at du bare vil ha en knapp for å erstatte knappene nbFirst, nbPrevious, nbNext og nbLast. Du kan bruke X- og Y-parametrene i HackNavMouseUp-prosedyren for å finne posisjonen til markøren da knappen ble sluppet. Nå, til denne ene knappen ("å styre dem alle") kan du legge ved et bilde som har 4 områder, hvert område antar å etterligne en av knappene du erstatter... har du poenget?