"Ok, de DBNavigator doet zijn werk om door gegevens te navigeren en records te beheren. Helaas willen mijn klanten een meer gebruikersvriendelijke ervaring, zoals aangepaste knopafbeeldingen en bijschriften, ..."
Deze aanvraag kwam van een Delphi-ontwikkelaar die op zoek was naar een manier om de kracht van de DBNavigator-component te vergroten.
De DBNavigator is een geweldig onderdeel - het biedt een VCR-achtige interface voor het navigeren door gegevens en het beheren van records in database-applicaties. Recordnavigatie wordt verzorgd door de knoppen First, Next, Prior en Last. Recordbeheer wordt verzorgd door de knoppen Bewerken, Posten, Annuleren, Verwijderen, Invoegen en Vernieuwen. In één component biedt Delphi alles wat u nodig hebt om uw gegevens te verwerken.
Zoals de auteur van de e-mailaanvraag ook al zei, mist de DBNavigator enkele functies zoals aangepaste glyphs, knopbijschriften en andere.
Veel Delphi-componenten hebben nuttige eigenschappen en methoden die voor een Delphi-ontwikkelaar als onzichtbaar ("beschermd") zijn gemarkeerd. Hopelijk kan, om toegang te krijgen tot dergelijke beschermde leden van een component, een eenvoudige techniek genaamd de "beschermde hack" worden gebruikt.
Eerst voegt u een bijschrift toe aan elke DBNavigator-knop, vervolgens voegt u aangepaste afbeeldingen toe en ten slotte schakelt u OnMouseUp elke knop in.
Van de "saaie" DBNavigator tot een van:
De DBNavigator heeft een beveiligde eigenschap Buttons. Dit lid is een reeks van TNavButton, een afstammeling van TSpeedButton.
Omdat elke knop in deze beschermde eigenschap van TSpeedButton erft, kunt u met "standaard" TSpeedButton-eigenschappen werken zoals: Caption (een string die het besturingselement voor de gebruiker identificeert), Glyph (de bitmap die op de knop verschijnt), Layout (bepaalt waar de afbeelding of tekst op de knop verschijnt) ...
Vanuit de DBCtrls-eenheid (waar DBNavigator is gedefinieerd) "leest" u dat de eigenschap beschermde knoppen wordt gedeclareerd als:
Toetsen: rangschikking[TNavigateBtn] van TNavButton;
Waar TNavButton van TSpeedButton erft en TNavigateBtn een opsomming is, gedefinieerd als:
TNavigateBtn =
(nbFirst, nbPrior, nbNext, nbLast, nbInsert,
nbDelete, nbEdit, nbPost, nbCancel, nbRefresh);
Merk op dat TNavigateBtn 10 waarden bevat, die elk een verschillende knop op een TDBNavigator-object identificeren. Laten we nu eens kijken hoe u een DBNavigator kunt hacken:
Stel eerst een eenvoudig Delphi-formulier voor gegevensbewerking in door ten minste een DBNavigator, een DBGrid, een DataSoure en een Dataset-object naar keuze te plaatsen (ADO, BDE, dbExpres, ...). Zorg ervoor dat alle componenten "verbonden" zijn.
Ten tweede, hack een DBNavigator door een overgeërfde "dummy" -klasse te definiëren, boven de Form-aangifte, zoals:
type THackDBNavigator = klasse(TDBNavigator);
type
TForm1 = klasse(TForm)
...
Vervolgens moet u enkele glyphs instellen om aangepaste bijschriften en afbeeldingen op elke DBNavigator-knop weer te geven. U kunt de component TImageList gebruiken en 10 afbeeldingen (.bmp of .ico) toewijzen, die elk een actie van een bepaalde knop van een DBNavigator vertegenwoordigen.
Ten derde, voeg in de OnCreate-gebeurtenis voor de Form1 een oproep toe zoals:
procedure TForm1.FormCreate (Sender: TObject);
SetupHackedNavigator (DBNavigator1, ImageList1);
einde;
Zorg ervoor dat u de verklaring van deze procedure toevoegt aan het privégedeelte van de formulierverklaring, zoals:
type
TForm1 = klasse(TForm)
...
privateprocedure SetupHackedNavigator (const Navigator: TDBNavigator;
const Glyphs: TImageList);
...
Ten vierde, voeg de procedure SetupHackedNavigator toe. De procedure SetupHackedNavigator voegt aangepaste afbeeldingen toe aan elke knop en wijst een aangepaste titel toe aan elke knop.
toepassingen Toetsen; // !!! vergeet niet
procedure TForm1.SetupHackedNavigator
(const Navigator: TDBNavigator;
const Glyphs: TImageList);
const
Bijschriften: rangschikking[TNavigateBtn] van string =
('Initial', 'Previous', 'Later', 'Final', 'Add',
'Erase', 'Correct', 'Send', 'Withdraw', 'Revive');
(*
Bijschriften: array [TNavigateBtn] van string =
('First', 'Prior', 'Next', 'Last', 'Insert',
'Verwijderen', 'Bewerken', 'Plaatsen', 'Annuleren', 'Vernieuwen');
in Kroatië (gelokaliseerd):
Bijschriften: array [TNavigateBtn] van string =
('Prvi', 'Prethodni', 'Slijedeci', 'Zadnji', 'Dodaj',
'Obrisi', 'Promjeni', 'Spremi', 'Odustani', 'Osvjezi');
*)
var
btn: TNavigateBtn;
beginfor btn: = Laag (TNavigateBtn) naar High (TNavigateBtn) doen met THackDBNavigator (Navigator) .Buttons [btn] dobegin// uit de ondertiteling const array
Bijschrift: = Bijschriften [btn];
// het aantal afbeeldingen in de eigenschap Glyph
NumGlyphs: = 1;
// Verwijder de oude glyph.
Glyph: = nul;
// Wijs de aangepaste toe
Glyphs.GetBitmap (Integer (BTN), Glyph);
// gylph boven tekst
Indeling: = blGlyphTop;
// later uitgelegd
OnMouseUp: = HackNavMouseUp;
einde;
einde; (* SetupHackedNavigator *)
Oké, laten we het uitleggen. U doorzoekt alle knoppen in de DBNavigator. Bedenk dat elke knop toegankelijk is vanuit de beveiligde eigenschap Matrix-knoppen, daarom is de behoefte aan de THackDBNavigator-klasse. Omdat het type knoppenreeks TNavigateBtn is, gaat u van de knop "eerste" (met de functie Low) naar de knop "laatste" (met de functie High). Voor elke knop verwijdert u eenvoudig de "oude" glyph, wijst u de nieuwe toe (uit de parameter Glyphs), voegt u het bijschrift toe uit de array Bijschriften en markeert u de lay-out van de glyph.
Merk op dat u kunt bepalen welke knoppen worden weergegeven door een DBNavigator (niet de gehackte) via de eigenschap VisibleButtons. Een andere eigenschap waarvan u de standaardwaarde mogelijk wilt wijzigen, is Hints - gebruik deze om Help-tips te geven naar keuze voor de afzonderlijke navigatieknop. U kunt de weergave van de Hints beheren door de eigenschap ShowHints te bewerken.
Dat is het. Dit is waarom je Delphi hebt gekozen!
Waarom zou je hier stoppen? U weet dat wanneer u op de knop 'nbNext' klikt, de huidige positie van de gegevensset wordt doorgeschakeld naar het volgende record. Wat als u, laten we zeggen, 5 records vooruit wilt verplaatsen als de gebruiker de CTRL-toets ingedrukt houdt terwijl u op de knop drukt? Wat dacht je daarvan?
De "standaard" DBNavigator heeft geen OnMouseUp -gebeurtenis - degene die de Shift-parameter van de TShiftState draagt - waarmee u kunt testen op de status van de Alt-, Ctrl- en Shift-toetsen. De DBNavigator biedt alleen de OnClick-gebeurtenis die u kunt afhandelen.
De THackDBNavigator kan echter eenvoudig de OnMouseUp-gebeurtenis weergeven en u in staat stellen de status van de bedieningstoetsen en zelfs de positie van de cursor boven de betreffende knop te "zien" wanneer erop wordt geklikt!
Om de OnMouseUp zichtbaar te maken, wijst u eenvoudig uw aangepaste procedure voor gebeurtenisafhandeling toe aan de OnMouseUp-gebeurtenis voor de knop van de gehackte DBNavigator. Dit is precies al gedaan in de procedure SetupHackedNavigator:
OnMouseUp: = HackNavMouseUp;
Nu kan de HackNavMouseUp-procedure er als volgt uitzien:
procedure TForm1.HackNavMouseUp
(Afzender: TObject; Knop: TMouseButton;
Shift: TShiftState; X, Y: geheel getal);
const MoveBy: geheel getal = 5;
beginif NIET (Afzender is TNavButton) vervolgens Uitgang;
geval TNavButton (Sender) .Index van
nbPrior:
als (ssCtrl in Shift) vervolgens
TDBNavigator (TNavButton (Sender) .Parent).
DataSource.DataSet.MoveBy (-MoveBy);
nbNext:
als (ssCtrl in Shift) vervolgens
TDBNavigator (TNavButton (Sender) .Parent).
DataSource.DataSet.MoveBy (moveBy);
einde;
einde, (* HackNavMouseUp *)
Houd er rekening mee dat u de handtekening van de HackNavMouseUp-procedure moet toevoegen in het privégedeelte van de formulierverklaring (in de buurt van de verklaring van de procedure SetupHackedNavigator):
type
TForm1 = klasse(TForm)
...
privateprocedure SetupHackedNavigator (const Navigator: TDBNavigator;
const Glyphs: TImageList);
procedure HackNavMouseUp (afzender: TObject; knop: TMouseButton;
Shift: TShiftState; X, Y: geheel getal);
...
Ok, laten we het nog een keer uitleggen. De HackNavMouseUp-procedure behandelt de OnMouseUp-gebeurtenis voor elke DBNavigator-knop. Als de gebruiker de CTRL-toets ingedrukt houdt terwijl hij op de knop nbNext klikt, wordt het huidige record voor de gekoppelde gegevensset "MoveBy" (gedefinieerd als constant met de waarde van 5) records vooruit verplaatst.
Yep. U hoeft hiermee niet te rotzooien als u alleen de status van de bedieningstoetsen hoeft te controleren wanneer op de knop is geklikt. Hier is hoe hetzelfde te doen in de "gewone" OnClick-gebeurtenis van de "gewone" DBNavigator:
procedure TForm1.DBNavigator1Click
(Afzender: TObject; Knop: TNavigateBtn);
functie CtrlDown: Boolean;
var
Staat: TKeyboardState;
beginnen
GetKeyboardState (staat);
Resultaat: = ((State [vk_Control] And 128) 0);
einde;
const MoveBy: geheel getal = 5;
begincase Knop van
nbPrior:
als CtrlDown vervolgens
DBNavigator1.DataSource.DataSet.MoveBy (-MoveBy);
nbNext:
als CtrlDown vervolgens
DBNavigator1.DataSource.DataSet.MoveBy (moveBy);
einde; //geval
einde, (* DBNavigator2Click *)
En eindelijk is het project klaar. Of je kunt doorgaan. Hier is een scenario / taak / idee voor u:
Stel dat u slechts één knop wilt gebruiken om de knoppen nbFirst, nbPrevious, nbNext en nbLast te vervangen. U kunt de X- en Y-parameters in de HackNavMouseUp-procedure gebruiken om de positie van de cursor te vinden toen de knop werd losgelaten. Nu, aan deze ene knop ("om ze allemaal te regeren") kunt u een afbeelding toevoegen die 4 gebieden heeft, elk gebied is verondersteld een van de knoppen na te bootsen die u vervangt ... ik snap het?