Skapa och anpassa knappar med DBNavigator

"Ok, DBNavigator gör sitt jobb med att navigera data och hantera poster. Tyvärr vill mina kunder ha en mer användarvänlig upplevelse, som anpassade knappgrafik och bildtexter,... "

Denna förfrågan kom från a Delphi-utvecklare söker efter ett sätt att förbättra kraften hos DBNavigator-komponenten.

DBNavigator är en utmärkt komponent - den tillhandahåller ett videobandspelar-liknande gränssnitt för att navigera data och hantera poster i databasapplikationer. Spelnavigering tillhandahålls av knapparna First, Next, Prior och Last. Posthantering tillhandahålls av knapparna Redigera, Skicka, Avbryt, Radera, Infoga och Uppdatera. I en komponent tillhandahåller Delphi allt du behöver för att använda dina data.

Som författaren till e-postförfrågan också uttalade saknar DBNavigator vissa funktioner som anpassade glyfer, knapptexter och andra.

En mer kraftfull DBNavigator

Många Delphi-komponenter har användbara egenskaper och metoder som är markerade osynliga ("skyddade") för en Delphi-utvecklare. Förhoppningsvis, för att få tillgång till sådana skyddade medlemmar av en komponent, kan en enkel teknik som kallas "skyddad hack" användas.

instagram viewer

Först lägger du till en bildtext till varje DBNavigator-knapp, sedan lägger du till anpassad grafik och slutligen aktiverar du OnMouseUp varje knapp.

Från den "tråkiga" DBNavigator till någon av:

  • Standard grafik och anpassade bildtexter
  • Endast bildtexter
  • Anpassad grafik och anpassade bildtexter

Låt oss rocka 'n' roll

DBNavigator har en skyddad knappegenskap. Denna medlem är en matris av TNavButton, en ättling till TSpeedButton.

Eftersom varje knapp i den här skyddade egenskapen ärver från TSpeedButton, kommer du att kunna arbeta med "standard" TSpeedButton-egenskaper som: Bildtext (en sträng som identifierar kontrollen till användaren), Glyph (bitmappen som visas på knappen), Layout (avgör var bilden eller texten ska visas på knapp)...

Från DBCtrls-enheten (där DBNavigator är definierad) "läser du" att den skyddade knappens egenskapen förklaras som:

Knappar: array[TNavigateBtn] av TNavButton;

Där TNavButton ärver från TSpeedButton och TNavigateBtn är en uppräkning, definierad som:

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

Observera att TNavigateBtn har 10 värden, var och en identifierar olika knappar på ett TDBNavigator-objekt. Låt oss nu se hur man hackar en DBNavigator:

Förbättrad DBNavigator

Ställ in en enkel Delphi-formulär genom att placera minst en DBNavigator, a DBGrid, en DataSoure och en Datasättobjekt du väljer (ADO, BDE, dbExpres, ...). Se till att alla komponenter är "anslutna".

För det andra, hacka en DBNavigator genom att definiera en ärftlig "dummy" -klass, ovanför formulärdeklarationen, som:

typ THackDBNavigator = klass(TDBNavigator);
typ
TForm1 = klass(TForm)
...

För att kunna visa anpassade bildtexter och grafik på varje DBNavigator-knapp måste du konfigurera några glyfer. Du kan använda TImageList-komponenten och tilldela 10 bilder (.bmp eller .ico), var och en representerar en åtgärd av en viss knapp i en DBNavigator.

För det tredje, i OnCreate-händelse för Form1, lägg till ett samtal som:

procedur TForm1.FormCreate (avsändare: TObject);
SetupHackedNavigator (DBNavigator1, ImageList1);
slutet;

Se till att du lägger till deklarationen för detta förfarande i den privata delen av formulärdeklarationen, som:

typ
TForm1 = klass(TForm)
...
privateprocedure SetupHackedNavigator (const Navigator: TDBNavigator;
const Glyphs: TImageList);
...

För det fjärde lägger du till SetupHackedNavigator-proceduren. Proceduren SetupHackedNavigator lägger till anpassad grafik till varje knapp och tilldelar en anpassad bildtext till varje knapp.

användningar knappar; //!!! glöm inte
procedur TForm1.SetupHackedNavigator
(const Navigator: TDBNavigator;
const Glyphs: TImageList);
const
Bildtexter: array[TNavigateBtn] av strängen =
('Initial', 'Föregående', 'Senare', 'Final', 'Lägg till',
'Radera', 'Rätt', 'Skicka', 'Återkalla', 'Återuppliva');
(*
Bildtexter: array [TNavigateBtn] of string =
('Först', 'Före', 'Nästa', 'Sista', 'Infoga',
'Radera', 'Redigera', 'Inlägg', 'Avbryt', 'Uppdatera');

i Kroatien (lokaliserad):
Bildtexter: array [TNavigateBtn] of string =
('Prvi', 'Prethodni', 'Slijedeci', 'Zadnji', 'Dodaj',
'Obrisi', 'Promjeni', 'Spremi', 'Odustani', 'Osvjezi');
*)
var
btn: TNavigateBtn;
beginfor btn: = Låg (TNavigateBtn) till Hög (TNavigateBtn) göra med THackDBNavigator (Navigator) .Knappar [btn] dobegin// från bildtexten const array
Bildtexter: = Bildtexter [btn];
// antalet bilder i egenskapen Glyph
NumGlyphs: = 1;
// Ta bort den gamla glyphen.
Glyph: = noll;
// Tilldela den anpassade
Glyfer. GetBitmap (heltal (btn), Glyph);
// gylph ovanför texten
Layout: = blGlyphTop;
// förklaras senare
OnMouseUp: = HackNavMouseUp;
slutet;
slutet; (* SetupHackedNavigator *)

Okej, låt oss förklara. Du upprepar alla knapparna i DBNavigator. Kom ihåg att varje knapp är tillgänglig från den skyddade knappens array-egenskap - därför behovet av THackDBNavigator-klassen. Eftersom typen av knappar array är TNavigateBtn, går du från "första" (med hjälp av Låg funktion) -knappen till "sista" (med hjälp av Hög funktion) en. För varje knapp tar du helt enkelt bort den "gamla" glyphen, tilldelar den nya (från Glyphs-parametern), lägger till bildtexten från bildtexten och markerar layouten för glyph.

Observera att du kan kontrollera vilka knappar som visas av en DBNavigator (inte den hackade) via egenskapen VisibleButtons. En annan egenskap vars standardvärde du kanske vill ändra är tips - använd den för att tillhandahålla hjälpavsnitt du väljer för den enskilda navigatorknappen. Du kan kontrollera visningen av tips genom att redigera egenskapen ShowHints.

Det är allt. Det är därför du har valt Delphi!

Ge mig mer!

Varför stanna här? Du vet att när du klickar på 'nbNästa' -knappen avanceras datasystemets nuvarande position till nästa post. Tänk om du vill flytta, låt oss säga, 5 poster framåt om användaren håller CTRL-tangenten medan han trycker på knappen? Hur låter det?

Den "standard" DBNavigator har inte OnMouseUp-händelsen - den som bär skiftparametern för TShiftState - vilket gör att du kan testa för Alt-, Ctrl- och Shift-tangenterna. DBNavigator tillhandahåller bara OnClick-händelsen som du kan hantera.

Men THackDBNavigator kan helt enkelt exponera OnMouseUp-händelsen och låta dig "se" statusen för kontrolltangenterna och till och med markörens placering ovanför den specifika knappen när du klickar!

Ctrl + Klicka: = 5 rader framåt

För att exponera OnMouseUp tilldelar du helt enkelt din anpassade händelseförfarande till OnMouseUp-händelsen för knappen på den hackade DBNavigator. Detta exakt har redan gjorts i SetupHackedNavigator-proceduren:
OnMouseUp: = HackNavMouseUp;

Nu kan HackNavMouseUp-förfarandet se ut:

procedur TForm1.HackNavMouseUp
(Avsändare: TObject; Knapp: TMouseButton;
Skift: TShiftState; X, Y: heltal);
const MoveBy: heltal = 5;
beginifINTE (Avsändaren är TNavButton) sedan Utgång;
fall TNavButton (avsändare) .Index av
nbPrior:
om (ssCtrl i Shift) sedan
TDBNavigator (TNavButton (avsändare). Förälder).
Datakälla. DataSet. MoveBy (-MoveBy);
nbNext:
om (ssCtrl i Shift) sedan
TDBNavigator (TNavButton (avsändare). Förälder).
Datakälla. DataSet. MoveBy (MoveBy);
slutet;
slutet; (* HackNavMouseUp *)

Observera att du måste lägga till signaturen för HackNavMouseUp-proceduren i den privata delen av formulärdeklarationen (nära förklaringen för SetupHackedNavigator-proceduren):

typ
TForm1 = klass(TForm)
...
privateprocedure SetupHackedNavigator (const Navigator: TDBNavigator;
const Glyphs: TImageList);
procedur HackNavMouseUp (avsändare: TObject; Knapp: TMouseButton;
Skift: TShiftState; X, Y: heltal);
...

Okej, låt oss förklara, en gång till. HackNavMouseUp-proceduren hanterar OnMouseUp-händelsen för varje DBNavigator-knapp. Om användaren håller CTRL-tangenten medan han klickar på nbNästa-knappen flyttas den aktuella posten för det länkade datasättet "MoveBy" (definierat som konstant med värdet på 5) poster framåt.

Vad? Alltför komplicerad?

Japp. Du behöver inte röra med allt detta om du bara behöver kontrollera statusen för kontrolltangenterna när du klickade på knappen. Så här gör du samma sak i den "vanliga" OnClick-händelse av den "vanliga" DBNavigator:

procedur TForm1.DBNavigator1Click
(Avsändare: TObject; Knapp: TNavigateBtn);
fungera CtrlDown: Boolean;
var
Tillstånd: TKeyboardState;
Börja
GetKeyboardState (stat);
Resultat: = ((Tillstånd [vk_Control] Och 128) 0);
slutet;
const MoveBy: heltal = 5;
begincase Knapp av
nbPrior:
om CtrlDown sedan
DBNavigator1.DataSource. DataSet. MoveBy (-MoveBy);
nbNext:
om CtrlDown sedan
DBNavigator1.DataSource. DataSet. MoveBy (MoveBy);
slutet; //case
slutet; (* DBNavigator2Click *)

Det är allt folk

Och slutligen är projektet klart. Eller så kan du fortsätta. Här är ett scenario / uppgift / idé för dig:

Låt oss säga att du bara vill ha en knapp för att ersätta knapparna nbFirst, nbPrevious, nbNext och nbLast. Du kan använda X- och Y-parametrarna i HackNavMouseUp-proceduren för att hitta markörens position när knappen släpptes. Nu, till den här knappen ("att styra dem alla") kan du bifoga en bild som har fyra områden, varje område antar att härma en av knapparna du ersätter... har du poängen?

instagram story viewer