2009-11-06 3 views
21

Gibt es einen bestimmten Zweck für die "Tag" -Eigenschaft von Delphi VCL-Komponenten? Ich habe ein paar Beispiele gegoogled, die es als eine 'Farbe'-Eigenschaft verwenden oder den Wert als eine Zeigeradresse verwenden, aber ist es "gute Praxis", es zu verwenden, oder wird es als "schlechte Praxis" betrachtet, wie es bindet die Programmlogik zur UI?Was ist der Zweck der Eigenschaft "Tag" von Delphi VCL-Komponenten?

+0

Dies gilt nicht für -just- Delphi, aber es ist immer noch eine sehr gute Frage mit ebenso guten Antworten. Nur ein Heads-Up – Kawa

Antwort

36

Die "Tag" -Eigenschaft ist dort als "Frachtcontainer" für alles, was Sie damit tun möchten.

Etwas, das oft für Ereignishandler verwendet wird, wenn Sie viele ähnliche Komponenten haben, die einen Ereignishandler teilen. Der Event-Handler kann seinen Aufrufer finden und dann seinen Tag-Wert abfragen, um weitere Informationen darüber zu erhalten, auf was er reagieren soll.

EDIT:

Beispiel: Ein Rechner App könnte die Zifferntasten mit ihren jeweiligen Zahlen markiert ... dumm und unvollständig Beispiel, aber Sie bekommen die Idee. Der Event-Handler könnte dann die Nummer ziehen, um die Anzeige und den Akkumulator direkt aus dem Tag hinzuzufügen, anstatt herausfinden zu müssen, welcher Knopf was zu tun hat.

+0

+1 für das Beispiel. –

11

Es ist ein Ort, um einer Komponente eine Information hinzuzufügen, auch wenn Sie nicht die Quelle für diese Komponente haben. Es sollte sorgfältig verwendet werden, da Sie es nur für einen Zweck pro Komponente verwenden können. Aus diesem Grund sollten Bibliotheken niemals verwenden.

+0

nur einmal verwendet? Wie in Sie können die Tag-Info nur einmal ändern? Also wenn ich etwas wie TCard.tag tun sollte: = 3; Ich kann später nicht TCard.tag: = 5; ? –

+0

Sie können es nur für einen Zweck gleichzeitig verwenden. Angenommen, Sie legen einen THelper auf demselben Formular ab, der damit beginnt, jedem gefundenen Tag Hilfstexte zuzuordnen. –

4

Wie andere gesagt haben, ist es ein Ort, um etwas zu setzen. In der Regel ist dies nützlich, wenn zwei Objekte über eine Objektreferenz oder einen Zeiger verknüpft werden. Das Tag hat genau die richtige Größe, um einen Zeiger zu halten. Wenn Sie beispielsweise ein Objekt an ein Element in einer Listbox binden möchten, wird es ziemlich einfach.

+2

und hoffentlich passt ein Zeiger immer noch in ein Tag, wenn 64-Bit Delphi ankommt ... – frogb

+1

@frogb: Und so ist es! –

3

Es kann auch für Gruppierungszwecke verwendet werden, sagen Sie, dass Sie auf alle Komponenten mit einem bestimmten Tag-Wert zugreifen möchten, unabhängig vom Typ der Komponente.

3

Es ist großartig! Ein Freebie. Ich benutze es die ganze Zeit, um eine zusätzliche Information zu speichern, die mit dem Objekt verbunden ist.

Oft speichere ich einen Zeiger auf eine zugehörige Datenstruktur oder manchmal eine ganze Zahl, die ein Index in ein anderes Array sein kann.

Sie können es als Zähler für den Zugriff auf das Objekt oder was auch immer verwenden.

Der einzige Nachteil ist, wenn Ihr Programm viel Speicher verwendet und Sie Millionen von Objekten haben, addieren sich diese 4 Bytes für jedes Tag, vor allem, wenn Sie es nicht verwenden. In diesem Fall möchten Sie möglicherweise für Ihren produktivsten Objekttyp eine eigene Version ohne das Tag erstellen.

+2

Das ist wahrscheinlich kein ernsthaftes Problem, da Ihre "Millionen von Objekten" sehr wahrscheinlich keine Tag-Eigenschaft haben. Nur VCL-Klassen haben es, und Sie neigen nicht dazu, all die vielen von ihnen auf einmal instanziiert zu haben. –

+0

Oh, du hast Recht. Die meisten Baum- und Listenelemente in Standard-Delphi haben keine Tags. Ich mixte das mit dem ElTree-Paket von LMDInnovative, das ich verwende, welches einen Tag auf jedem Gegenstand im Baum hat. Meine Bäume können Millionen von Objekten haben, und als Ergebnis habe ich Millionen von Tags. Aber der wirkliche Punkt ist, dass ich liebe, diese Fähigkeit zu haben – lkessler

+0

Baum- und Listenelemente haben eine "Daten" -Eigenschaft, die dem "Tag" entspricht. –

3

Sie haben zwei Tasten auf dem Formular, auf das Sie den Tag = 1 gesetzt, und den anderen Tag = 2. Sie jetzt das gleiche auf beiden Tasten OnClick Ereignis zuordnen und den Code wie folgt winden:

procedure TForm28.Button1Click(Sender: TObject); 
begin 
    case (Sender as TButton).Tag of 
    1: Caption := 'you pressed button 1'; 
    2: Caption := 'you pressed button 2'; 
    end; 
end; 

oder kompaktere:

procedure TForm28.Button1Click(Sender: TObject); 
begin 
    Caption := 'you pressed button ' + IntToStr((Sender as TButton).Tag); 
end; 

Grundsätzlich Tag lassen Sie erkennen, welche Kontrolle das Ereignis ausgelöst. Denken Sie, wenn Sie ein Formular mit dynamisch erstellten Schaltflächen haben ... eine Liste mit Benutzern aus der Datenbank, und auf jedem Datensatz setzen Sie eine Schaltfläche "Benutzer löschen". In dieser Situation können Sie kein Ereignis für jede Schaltfläche erstellen, Sie erstellen ein Ereignis, das allen Schaltflächen zugewiesen wird ... und Sie können beispielsweise die Benutzer-ID in die Variable einfügen.Auf diese Weise wissen Sie bei der Implementierung des Ereignisses für die Handhabung aller Schaltflächen, welcher Benutzer gelöscht werden soll.

+0

Es gibt Kompilierfehler im Code: '(Sender as TButton)' sollte '(Sender as TButton) .Tag' sein. – ZzZombo

+0

@ZzZombo Sie haben Recht, danke –

2

I Verwenden Sie Tags die ganze Zeit. hier sind einige Beispiele;

ein einfaches Beispiel: Sie haben ein Notebook (wie ein pagecontroll ohne Reiter) so können Sie Tasten als Registerkarten definieren und

NoteBook.ActivePage := TButton(Sender).Tag; 

eine kompliziertere Probe schreiben; eine Ganzzahl kann 16 bitweise Buleans enthalten; Ich kann dann den Absender zu 16 Bedingungen prüfen zu entscheiden, wie die pricedure

If (BitCheck (Bit2,TButton(sender).tag=True) And BitCheck(bit12,TButton(Sender).Tag=False) Then 
Begin 
end; 

If (BitCheck (Bit9,TButton(sender).tag=True) Or BitCheck(bit14,TButton(Sender).Tag=True) Then 
Begin 
end; 

Sie die

5

Ich habe einige grundlegende Probleme mit der Tag-Eigenschaft Idee fortzusetzen. Nun, nicht genau diese Eigenschaft selbst, weil es wie vorgesehen funktioniert.

Im Allgemeinen halte ich die Verwendung von universellen/allgemeinen/Mehrzweckvariablen für eine "schlechte Praxis". Sie können beim Debuggen nützlich sein, sind aber in der produktions-/unternehmenskritischen Umgebung sehr schädlich. Sie verringern die Lesbarkeit und Verständlichkeit des Codes, weil niemand weiß, was ein Tag-Attribut oder eine Eigenschaft tut. Natürlich wissen Sie, warum Sie diese Variable verwenden. Aber früher oder später wirst du vergessen (ich weiß, du wirst) und sich auf diesen Wert zu verlassen, macht alles komplizierter. Deshalb sollten wir jede Variable und Eigenschaft richtig benennen, um zu verstehen, was der Code tut.

Verwenden der Tag-Eigenschaft ist nur eine Umgehung/Verknüpfung, um die Implementierung von verständlichem und gut geschriebenem Code zu vermeiden. Dies ist die Praxis und es macht süchtig. Wenn Sie das nächste Mal einen neuen ganzzahligen Wert speichern müssen, der an eine Komponente gebunden ist, verwenden Sie die Eigenschaft Tag, ohne eine andere Möglichkeit zum Speichern der gewünschten Werte zu berücksichtigen. Das Speichern eines Zeigers in der Tag-Eigenschaft ist eine schreckliche Idee: Sie müssen diesen Wert jedes Mal, wenn Sie Zeiger debuggen, umsetzen.

Sagen Sie mir: Wie oft haben Sie sich in einer Situation gefunden, in der Sie einen neuen Wert in der Tag-Eigenschaft speichern wollten, aber Sie haben festgestellt, dass diese Eigenschaft bereits für einen anderen Zweck verwendet wird (wenn nur ein 'Tag2 "Eigenschaft in jeder Komponente ...".

+2

Tag bereits verwendet? Kein Problem. benutze HelpContext Ja, ich verstehe deinen Standpunkt. –