Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - Property "Checked" verbergen, soll aber vorhanden bleiben
galagher - Mi 11.12.13 19:43
Titel: Property "Checked" verbergen, soll aber vorhanden bleiben
Hallo!
Wie bekomme ich es hin, dass die Property "Checked" einer selbstgeschriebenen Komponente zwar intern in der Komponente verwendet werden kann, man sie aber nicht mehr "von aussen" benutzen kann?
Ich habe die Property "Checked" durch eine Prozedur SetChecked ersetzt, wobei die Komponente intern (also in ihrem Code) diese Property nutzt. Ich will nun nicht, dass sie von aussen sichtbar ist, will sie also verbergen.
Ich meine das so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| unit ImageRadioButtonListBox; procedure TImageRadioButtonListBox.begin Checked[Value] := True; end;
function TImageRadioButtonListBox.begin Result := (Checked[Value]); end;
unit Unit1; begin ImageRadioButtonListBox1.Checked[1] := True;
ImageRadioButtonListBox1.SetChecked(1); end; |
Delete - Mi 11.12.13 20:39
Dann laß doch in deiner Klasse einfach den Setter weg. Damit kannst du Checked zwar noch auslesen, aber nicht mehr setzen. Zusätzlich führst du in deiner Klasse die Methode SetChecked ein, die Checked auf True setzt.
WasWeißDennIch - Mi 11.12.13 21:01
Und wo ist da der Unterschied? Ob ich eine Methode SetChecked einführe oder einen Setter benutze (den ich im Übrigen auch SetChecked nennen würde), ist doch völlig wumpe.
Delete - Mi 11.12.13 21:06
WasWeißDennIch hat folgendes geschrieben : |
Und wo ist da der Unterschied? Ob ich eine Methode SetChecked einführe oder einen Setter benutze (den ich im Übrigen auch SetChecked nennen würde), ist doch völlig wumpe. |
Sag das doch galagher und nicht mir :roll:
Schließlich will doch er ein Property, das man "nicht mehr 'von aussen' benutzen kann", aber dann doch wieder von außen benutzen kann.
galagher - Mi 11.12.13 21:07
Perlsau hat folgendes geschrieben : |
Dann laß doch in deiner Klasse einfach den Setter weg. Damit kannst du Checked zwar noch auslesen, aber nicht mehr setzen. Zusätzlich führst du in deiner Klasse die Methode SetChecked ein, die Checked auf True setzt. |
Das Problem ist, in meiner Komponente habe ich kein eigenes
property Checked, das ist in der Klasse, von der ich abgeleitet habe, also in TCheckListBox.
Meine Komponente verwendet Checked der Klasse TCheckListBox, um mit den dort vorhandenen CheckBoxes zu arbeiten, die ich aber im DrawItem nicht darstelle. Ich habe DrawItem ohne
inherited überschrieben, es werden jetzt statt CheckBoxes RadioButtons gezeichnet.
Checked bezieht sich weiterhin auf die (nun unsichtbaren) CheckBoxes, ich frage den Status ab und verwende ihn für die RadioButtons. Nun bewirkt der Aufruf
ImageRadioButtonListBox1.Checked[1] := ...; nichts, es wird zwar die entsprechende CheckBox gesetzt, aber dabei weder der zugehörige Code ausgeführt noch das RadioButton gesetzt.
Ziemlich kompliziert zu erklären...
Naja, Checked soll eben nur noch intern vorhanden sein.
jaenicke - Mi 11.12.13 21:12
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TImageRadioButtonListBox.begin inherited Checked[Value] := True; end;
function TImageRadioButtonListBox.begin Result := inherited Checked[Value]; end; |
Allerdings kommt man per Cast auch jederzeit wieder von außen heran. Einmal eingeführte Properties kann man nicht wieder entfernen. Deshalb solltest du von TCustomXXX ableiten statt von der fertigen Komponente mit den veröffentlichten Properties, dann ist Checked auch von außen nicht erreichbar, wenn du es nicht selbst veröffentlichst...
WasWeißDennIch - Mi 11.12.13 21:20
Exakt, der Sinn der TCustomXXX-Komponenten ist ja genau der, dass zwar die allermeisten Properties bereits vorhanden, aber als protected deklariert sind. Abgeleitete Klassen tun im einfachsten Fall nichts anderes, als diese dann zu veröffentlichen.
galagher - Mi 11.12.13 21:25
jaenicke hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TImageRadioButtonListBox.begin inherited Checked[Value] := True; end;
function TImageRadioButtonListBox.begin Result := inherited Checked[Value]; end; | Allerdings kommt man per Cast auch jederzeit wieder von außen heran. |
Da komme ich ja trotzdem auch einfach so noch ran!
jaenicke hat folgendes geschrieben : |
Einmal eingeführte Properties kann man nicht wieder entfernen. |
Ich weiss! Ich will es ja auch nur verbergen.
jaenicke hat folgendes geschrieben : |
Deshalb solltest du von TCustomXXX ableiten |
Es gibt aber kein TCustomCheckListbox, denn TCheckListbox ist von TCustomListBox abgeleitet, dort gibt's aber wiederum kein Checked.
WasWeißDennIch - Mi 11.12.13 21:28
Das wirst Du dann selbst einführen müssen.
[edit] Aber welchen Sinn soll es haben, eine Checked-Property für eine Liste von Radiobuttons zu deklarieren? Wäre da so etwas wie CheckedIndex o.ä. nicht zielführender? Das fiel mir gerade mal so ein. [/edit]
galagher - Mi 11.12.13 21:35
WasWeißDennIch hat folgendes geschrieben : |
Das wirst Du dann selbst einführen müssen. |
Ja, nur muss ich dann alles eben nachbauen, was ich so bequem aus der Vorfahrklasse übernehmen kann. Dann habe ich leider, so wie es aussieht, auch das von aussen unnütze Checked.
Ich kann Checked andererseits auch nicht überschreiben im Sinne von "bei Aufruf von Checked führe Prozedur SetChecked aus", weil Checked ja intern noch verwendet wird. Wenn ich das mache, kommt es zu einem Stapelüberlauf, weil Checked die Prozedur SetChecked aufruft, wo dann Checked verwendet wird, das SetChecked aufruft, wo dann Checked verwendet wird usw.
Also kann man da nichts machen ausser eine neue Komponente bauen?
jaenicke - Do 12.12.13 00:04
galagher hat folgendes geschrieben : |
Ich kann Checked andererseits auch nicht überschreiben im Sinne von "bei Aufruf von Checked führe Prozedur SetChecked aus", weil Checked ja intern noch verwendet wird. Wenn ich das mache, kommt es zu einem Stapelüberlauf, weil Checked die Prozedur SetChecked aufruft, wo dann Checked verwendet wird, das SetChecked aufruft, wo dann Checked verwendet wird usw. |
Mit inherited gibt es keinen Stapelüberlauf.
Das Problem ist aber, dass du keine Property überschreiben kannst. Du kannst nur eine gleichnamige einführen. Sobald man aber dann mit dem Vorgängertyp arbeitet (Cast, Variablentyp, ...) wird auch wieder dessen Property benutzt statt deiner.
galagher hat folgendes geschrieben : |
Also kann man da nichts machen ausser eine neue Komponente bauen? |
Ja. Das macht aber ohnehin am meisten Sinn denke ich, wenn ich mir den relativ geringen Umfang des Quelltextes der genannten Komponenten so anschaue...
galagher - Do 12.12.13 19:21
jaenicke hat folgendes geschrieben : |
Mit inherited gibt es keinen Stapelüberlauf. |
Dann hab ich wohl beim Testen irgendwo ein
inherited vergessen. Jetzt funktioniert es, ich kann "mein"
Checked von der aufrufenden Unit aus verwenden, intern in der Klasse wird
inherited Checked verwendet. So soll es sein! :D
jaenicke hat folgendes geschrieben : |
Das Problem ist aber, dass du keine Property überschreiben kannst. |
Ich meinte dabei, eine eigene Property Checked, die etwas anderes macht als die der Vorfahrklasse.
Wirklich sauber, ich weiss, wäre es ja, die RadioButtons zur Laufzeit dynamisch zu erzeugen, dann kann ich deren Checked direkt benutzen. Ein wenig dreckig ist es zugegebenermassen schon, in DrawItem das
inherited wegzulassen und die originalen CheckBoxes zu verstecken, die aber dennoch da sind, und dann deren Status für die bloss gezeichneten RadioButtons zu verwenden. Aber die Idee ist doch gut, oder? :mrgreen:
Da ich DrawItem ja nun nicht nutzen kann, habe ich diese Property mit
UnlistPublishedProperty aus dem OI entfernt.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!