Autor Beitrag
Jojo2004
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31


D6 Pers
BeitragVerfasst: Do 25.03.04 23:25 
Hi Leute,

wieder mal ein Anfänger Problem, vielleicht kann mir jemand einen Tipp geben.
Ich habe mehrere Labels zu denen jeweils eine CheckBox gehört. Wenn ich die CheckBox auf True setze, soll das dazugehörige Label die Farbe verändern. Das ist aber nicht das Problem, sondern ich möchte das ganze mit (Sender) nur 1x schreiben und den CheckBoxen dann zuweisen.
Wie bekomme ich die Verbindung zum dazugehörigen Label?

Für ein Label ist das kein Problem.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TFormUebersichtMS.Button1Click(Sender: TObject);
     var LabelSender : TLabel;
   begin
      LabelSender := TLabel(Sender);
      if LabelSender.Font.Color =clred then
      LabelSender.Font.Color :=clWindow
      else if LabelSender.Font.Color =clred then
   end;


Ich hatte es über ein Panel versucht, aber ich bekomm´s nicht geregelt.

Also ich möchte eine CheckBox A anklicken und Label (A) wird rot. Wenn ich CheckBox B anklicke, wird Label B rot usw.

Ich hoffe ich konnte mein Problem klar machen.

Danke Euch für Eure Hilfe.

Moderiert von user profile iconMotzi: Delphi-Tags hinzugefügt.
Brainiac
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 25.03.04 23:45 
Mich wundert erstmal, dass dein Code mit dem Button funktioniert
Du weist einem TLabel ja den Sender zu, der aber eigentlich hier ein TButton ist.
Weil beide die Eigenschaft Font besitzen, könnte das sogar ohne Fehler gehen, aber dann müsste dein Button die Farbe ändern und nicht das Label.

Was du relativ einfach realisieren könntest, wäre die Farbe der eigenen Caption deiner Checkbox zu verändern, aber eine direkte Verbindung zwischen einem Label und einer Checkbox wie du sie dir vorstellst, wird nicht so leicht gehen.

Eine Möglichkeit wäre, bei Programmstart dem 'Tag' der Checkbox das passende Label zuzuweisen.
Der Tag ist nur leider ein Integer, weswegen dann ziemlich viele Typecasts auf dich zukämen, aber gehen würde es.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm1.FormCreate(Sender: TObject);
begin
 CheckBox1.Tag:=Integer(Label1);
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
 TLabel(TCheckBox(Sender).Tag).Font.Color:=clRed;
end;
Jojo2004 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31


D6 Pers
BeitragVerfasst: Fr 26.03.04 00:06 
Erst mal Danke für die Antwort.

Ich blende den Button aus und weise die procedure dem Labeln zu.
Es funktioniert einwandfrei.

Deine Anregung habe ich gleich mal ausgetestet. Klappt super 1000 Dank.
Jojo2004 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31


D6 Pers
BeitragVerfasst: Fr 26.03.04 09:59 
Ich hab doch noch mal ne Frage.

Wie kann ich es denn machen, wenn zu diesem Label mehr als nur eine CheckBox gehört?
Z.B. zu Label1 gehören Checkbox1 und Label2.

Ich weiß immer diese Anfängerfragen,
aber manchmal ist man zu neugierig um zu warten bis man es irgendwo gelesen hat.
MartinPb
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 698



BeitragVerfasst: Fr 26.03.04 10:25 
Die Ausführung von Brainiac ist zwar interresant, aber vor allem für Anfänger schwer nachvollziehbar. Hier der "normale" Weg. Obwohl es eine CheckBox1Click Prozedur ist, so wird sie von allen CheckBox Komponenten über onClick angesteuert, d.h. im ObjektInspektor muß man im OnClick Event bei allen CheckBox Komponenten die CheckBox1Click Prozedur benutzen.

Weiterhin hab ich aus Gründen der Übersicht auf ELSE verzichtet. Natürlich kannst du es einsetzten.

Hier im Beispiel wird einfach geprüft ob der Sender eine bestimte Komonente ist. Wenn ja, dann wird der Block ausgeführt.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  if Sender = CheckBox1 then
  begin
    with Label1.Font do
      if TCheckBox(Sender).Checked then Color := clRed else Color := clBlack;
  end;

  if Sender = CheckBox2 then
  begin
    with Label2.Font do
      if TCheckBox(Sender).Checked then Color := clRed else Color := clBlack;
  end;
end;

_________________
Gruß
Martin
Jojo2004 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31


D6 Pers
BeitragVerfasst: Fr 26.03.04 10:37 
Hi MartinPb

Wäre das nicht genauso umständlich, als wenn ich es zu jeder CheckBox einzeln eintrage?
Das wollte ich eigentlich nicht so gerne.

Aber auf jeden Fall Danke
MartinPb
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 698



BeitragVerfasst: Fr 26.03.04 10:49 
Du benutzt bei dieser Variante nur eine einzige Prozedur. Wenn du es einzeln abfragst, dann ist es üblich pro CheckBox eine Prozedur zu nehmen. Wenn es aber aufwendig ist, dann kannst du versuchen die Methode von Brainiac zu modifizieren.

_________________
Gruß
Martin
Jojo2004 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31


D6 Pers
BeitragVerfasst: Fr 26.03.04 11:00 
Zur Übersicht meines Vorhabens.

Nummer CheckBox Titel
01 [] Titel1
02 [] Titel2
03 [] Titel3
usw.

wenn im Titel 1 nichts steht, soll die Nummer 01 und dazugehörige CheckBox ausgeblendet werden.
Wie das ausblenden geht ist keine Frage, aber ich möchte nur 1 procedure für alle Schreiben.
(Was ja möglich sein müsste)
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Fr 26.03.04 12:15 
Ich würde einen viel allgemeineren Weg nehmen.. wenn die Checkboxes alle durchnumerierte Namen haben (Checkbox1, Checkbox2, .. CheckboxX) und die Labels auch entsprechend (Label1, Label2, ... LabelX) dann kann man ganz einfach über FindComponent gehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TForm1.CheckBoxClick(Sender: TObject);
var
  aLabel: TLabel;
begin
  aLabel := FindComponent('Label' + Copy(TComponent(Sender).Name, 9, Length(TComponent(Sender).Name) - 9));
  if Assigned(aLabel) then
  begin
    if TCheckBox(Sender).Checked then 
      aLabel.Color := clRed
    else 
      aLabel.Color := clBlack;
  end;
end;

So ungefähr... eventuell muss die Stringzerlegung noch ein bisschen korrigiert werden (hab das ganze jetzt nicht getestet)..

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Jojo2004 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31


D6 Pers
BeitragVerfasst: Fr 26.03.04 12:46 
Hi Motzi

Leider habe ich bisher noch nicht mit FindComponent gearbeitet. Bin also in dieser Richtung noch etwas doof.
Ich bin aber lernwillig und möchte kapieren was ich da tue. Könntest Du mir etwas zu dem schreiben, was Du zwischen dem 1.begin und dem 2. machst und welche Auswirkungen das hat?
Oder vielleicht wo ich etwas darüber lesen kann.
Wäre echt super.

Danke
MartinPb
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 698



BeitragVerfasst: Fr 26.03.04 15:35 
Mit FindComponent suchst du eine Komponente per Komponenten-Name. Wenn du zum Beispiel eine Komponente mit dem Namen CheckBox1 hast, dann kanst du sie mit FindComponent suchen und zugreifen. In dem Beispiel oben geht Motzi davon aus, daß die CheckBox die gleiche Nummer hat wie das zugehörige Label, d.h. CheckBox1 > Label1. Beide haben die 1. Jetzt muß man nur noch die "1" aus "ChechBox1" rauskopieren und an "Label" String anhängen, so daß ein "Label1" String rauskommt. So kannst du anhand ders Checkbox Namen an den Label Namen kommen. Der Rest ist einfach. Die Variable aLabel bekommt die gleiche Adresse die per FindComponent gefunden wurde. Schon kannst du aLabel als den normalen Label benutzen.

Das ganze ist relativ pfiffig, aber leicht instabil. Wenn es einen Label mit dem Namen nicht gibt, dann gibt es eine Fehlermeldung. Zumindest glaube ich es. Ich hab gerade kein Delphi da um es zu testen. Auch müssen die CheckBox und Label Komponenten die gleiche Zahl haben. Und sie müssen mit "CheckBox" und "Label" anfangen. Aber das alles kann man noch verfeinern. Nur kriegst du mit dieser Methode maximal ein Label geändert. Ich würde mich langsam mit meinem Tip anfreunden.

_________________
Gruß
Martin
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Fr 26.03.04 17:06 
MartinPb hat folgendes geschrieben:
Mit FindComponent suchst du eine Komponente per Komponenten-Name. Wenn du zum Beispiel eine Komponente mit dem Namen CheckBox1 hast, dann kanst du sie mit FindComponent suchen und zugreifen. In dem Beispiel oben geht Motzi davon aus, daß die CheckBox die gleiche Nummer hat wie das zugehörige Label, d.h. CheckBox1 > Label1. Beide haben die 1. Jetzt muß man nur noch die "1" aus "ChechBox1" rauskopieren und an "Label" String anhängen, so daß ein "Label1" String rauskommt. So kannst du anhand ders Checkbox Namen an den Label Namen kommen. Der Rest ist einfach. Die Variable aLabel bekommt die gleiche Adresse die per FindComponent gefunden wurde. Schon kannst du aLabel als den normalen Label benutzen.

Gut erklärt! :)

Zitat:
Das ganze ist relativ pfiffig, aber leicht instabil. Wenn es einen Label mit dem Namen nicht gibt, dann gibt es eine Fehlermeldung. Zumindest glaube ich es. Ich hab gerade kein Delphi da um es zu testen. Auch müssen die CheckBox und Label Komponenten die gleiche Zahl haben. Und sie müssen mit "CheckBox" und "Label" anfangen. Aber das alles kann man noch verfeinern. Nur kriegst du mit dieser Methode maximal ein Label geändert. Ich würde mich langsam mit meinem Tip anfreunden.

Nein, es gibt keinen Fehler! Wird kein Steuerelement mit dem entsprechenden Namen gefunden so gibt FindComponent nil zurück... und da ich ja in der nächsten Zeile per Assigned prüfe ob aLabel eine gültige Referenz hat gibt es keinen Fehler..! Und dass sie mit "Checkbox" und "Label" anfangen müssen ist auch nicht pflicht..! Man muss es dann halt nur im Code auch entsprechend anpassen.. nur die Nummerierung muss halt passen...

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Jojo2004 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31


D6 Pers
BeitragVerfasst: Fr 26.03.04 17:27 
Irgendwie geht das bei mir noch nicht Richtig.
Ich habe ( Label1, CheckBox1,LabelA1 ) und ( Label2, CheckBox2, LabelA2 ) usw.
Die jeweils in Verbindung stehen sollen.

Das hatte ich unter FormActivate für jeden Label eingetragen und hätte es gerne etwas kürzer.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
    if (LabelSheet22.Caption <> '') then
      begin
        Label22.Font.Color :=clred;
        CheckBox22.Visible :=True
      end
     else begin
        Label22.Font.Color :=clWindowText;
        CheckBox22.Visible :=False;
      end;


Vielleicht geht das auch gar nicht, würde mich aber stark interessieren.

Moderiert von user profile iconMotzi: Delphi-Tags hinzugefügt.
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Fr 26.03.04 17:37 
Naja.. man "kann" schon:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
const
  szColors: array [Boolean] of TColor = (clWindowText, clred);

  Label22.Font.Color := szColors[LabelSheet22.Caption <> ''];
  CheckBox22.Visible := LabelSheet22.Caption <> '';

Ob das allerdings so "sinnvoll" ist ist eine andere frage..

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Jojo2004 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31


D6 Pers
BeitragVerfasst: Fr 26.03.04 17:55 
Hab mich nich richtig ausgedrückt,
ich möchte das nicht 75 mal schreiben, sondern suche eine Möglichkeit das 1x zu schreiben und für alle Gültig zu machen.

Trotzdem Danke
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Fr 26.03.04 18:12 
Achso.. ja, auch wieder per FindComponent..! Einfach in einer Schleife immer den Namen des gesuchten Steuerelements zusammenstückeln, per FindWindow suchen und nach einem Typecast kannst du dann auch die gewünschten Eigenschaften ändern..!

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Jojo2004 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31


D6 Pers
BeitragVerfasst: Fr 26.03.04 18:18 
Hättest Du für mich mal ein Beispiel? Ich wäre Dir sehr Dankbar.

Bin noch Doof, werde es aber nicht bleiben

Tschau und Danke
MartinPb
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 698



BeitragVerfasst: Fr 26.03.04 19:44 
Wieso Beispiel? Oben steht doch ein Beispiel.

_________________
Gruß
Martin
Brainiac
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 27.03.04 08:59 
@Motzi:
Nebenbei müsste es...Test := TLabel(FindComponent('Label' + Copy(TComponent(Sender).Name, 9, Length(TComponent(Sender).Name) - 9)));...heißen, sonst meckert der Compiler wegen inkompatiblen Typen.

Nebenbei:
Ihr wollt mir doch nicht erzählen, dass das für einen Anfänger leichter verständlich ist als mein Ansatz, oder??
Besonders schnell und ressourcensparend ist es nebenbei auch nicht.
Der Vorteil ist nur, dass es mit einer beliebigen Anzahl von Komponenten funktioniert, ohne dass der Code geändert werden muss.

Also ich denke du solltest vielleicht wirklich beim Ansatz von MartinPb bleiben.
Der ist schnell, simpel und leicht modifizierbar.

Meiner ist halt noch etwas schneller, besonders wenn du gleich eine Referenz auf 'Font.Color' in den Tag schreiben würdest, aber dafür musst du halt wirklich schon genauer verstehen, was du tust, um keine Fehler zu produzieren.
MartinPb
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 698



BeitragVerfasst: Sa 27.03.04 12:09 
Brainiac hat folgendes geschrieben:
Nebenbei:
Ihr wollt mir doch nicht erzählen, dass das für einen Anfänger leichter verständlich ist als mein Ansatz, oder??


Doch, bzw. FindComponent ist nur ein Tip, weil es Normalwissen ist. Sowas muß man sowieso wissen. Dein Hinweis ist ein Trick. Es ist irgendetwas das funktioniert. Es ist nicht schlechter, nur eben Trick17.

_________________
Gruß
Martin