Hallo,
die CASE Version ist meiner Meinung nach auch übersichtlicher. Aber Du wolltest ja eine funktionierende Version mit if then else
Code: Alles auswählen
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if (Shape1.Brush.Color = clWhite) and (Shape2.Brush.Color = clWhite) and (Shape3.Brush.Color = clWhite) then
Shape1.Brush.Color := clRed
else if (Shape1.Brush.Color = clRed) and (Shape2.Brush.Color = clWhite) then
Shape2.Brush.Color := clYellow
else if (Shape1.Brush.Color = clRed) and (Shape2.Brush.Color = clYellow) then
begin
Shape1.Brush.Color := clWhite;
Shape2.Brush.Color := clWhite;
Shape3.Brush.Color := clLime;
end else if (Shape3.Brush.Color = clLime) then
begin
Shape3.Brush.Color := clWhite;
Shape2.Brush.Color := clYellow;
end else
begin
Shape1.Brush.Color := clRed;
Shape2.Brush.Color := clWhite;
end;
end;
Das geht zwar, ist aber nur schwer zu lesen und vor allem zu verstehen.
Spätestens wenn Deine Programme größer werden, wird diese Vorgehensweise schnell unübersichtlich.
Am Anfang etwas schwieriger zu verstehen, aber später ungemein hilfreich ist, Properties zu verwenden.
Als erstes deklarierst Du einen Datentyp, welcher nur die möglichen Ampelzustände definiert.
Am besten oberhalb der Definition des Formulares, weil Du diesen neuen Datentyp dann auch gleich im Formular verwenden kannst.
Code: Alles auswählen
type
// Typ, welcher die möglichen Ampelstellungen definiert
TAmpelstatus = (asRot, asRotGelb, asGruen, asGelb);
{ TForm1 }
TForm1 = class(TForm)
BitBtn1: TBitBtn;
...
Im Formular deklarieren wir ein Feld fAmpelstatus vom Typ TAmpelstatus und zwar im privaten Bereich des Formulares sowie eine Procedure SetAmpelstatus.
Im public Teil des Formulares deklarierst Du eine property Ampelstatus.
Diese Property kannst Du im Programm verwenden wie eine Variable, also einen Wert zuweisen oder den aktuellen Wert abfragen.
Einfach durch eine Zuweisung der Form
wird automatisch das richtige Shape mit der richtigen Farbe befüllt.
Das klingt am Anfang vielleicht etwas umständlich, erleichtert aber später das Leben erheblich.
Hier die Definition
Code: Alles auswählen
TForm1 = class (TForm)
...
private
{ private declarations }
fAmpelstatus : TAmpelstatus;
procedure SetAmpelstatus(Value : TAmpelstatus);
public
{ public declarations }
property Ampelstatus : TAmpelstatus read fAmpelstatus write SetAmpelstatus;
end;
Durch die Angabe write SetAmpelstatus bei der Definition der property Ampelstatus ruft der Compiler automatisch die angegebene Procedure auf, wenn der "Variablen" Ampelstatus ein Wert zugewiesen wird und zwar egal wie oder wo.
Diese Procedure ist die einzige Stelle im Programm, welche sich um die richtigen Farbgebungen kümmert.
Du könntest z.B. in Deinem Formular noch 4 Radiobuttons mit "Rot", "Rot/Gelb", "Grün" und "Gelb" einfügen und in der jeweiligen Ereignisbehandlungsroutine für OnClick
schreiben: Ampelstatus := asRot;
Die Implementierung der Methode (so werden Prozeduren und Funktionen genannt, wenn Sie in einer Klasse verwendet werden) SetAmpelstatus schaut dann so aus.
Code: Alles auswählen
procedure TForm1.SetAmpelstatus(Value: TAmpelstatus);
begin
if (fAmpelstatus <> Value) then
begin
fAmpelstatus := Value;
Shape1.Brush.Color := clWhite;
Shape2.Brush.Color := clWhite;
Shape3.Brush.Color := clWhite;
case fAmpelstatus of
asRot : Shape1.Brush.Color := clRed;
asRotGelb : begin
Shape1.Brush.Color := clRed;
Shape2.Brush.Color := clYellow;
end;
asGelb : Shape2.Brush.Color := clYellow;
asGruen : Shape3.Brush.Color := clLime;
end;
end;
end;
Der Einfachheit halber definiert man nun noch eine Methode mit dem Namen "NextStatus", welche dem aktuellen Status der Ampel entsprechend den nächsten richtigen
Schaltzustand einstellt.
Unter public fügst Du einfach
ein und die Implementation sieht so aus:
Code: Alles auswählen
procedure TForm1.NextStatus;
begin
case Ampelstatus of
asRot : Ampelstatus := asRotGelb;
asRotGelb : Ampelstatus := asGruen;
asGruen : Ampelstatus := asGelb;
asGelb : Ampelstatus := asRot;
end;
end;
Im OnClick des Buttons rufst Du diese nun einfach auf:
Code: Alles auswählen
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
NextStatus;
end;
Im Anhang ist das Projekt nochmal zum Nachvollziehen. Hier ist noch ein zusätzliches Feld fUpdating vorhanden.
Hintergrund ist folgender. Wenn der Button die Ampel auf die nächste Stufe schaltet, soll auch der entsprechende Radiobutton aktiviert werden.
Da dieser aber wiederum in seinem OnClick Event den Status der Ampelschaltung ändert, käme es zu einer Endlosschleife.
Gruß
Michl