Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Hä? Warum ist das Ändern von Checked ein Click? (https://www.delphipraxis.net/213272-hae-warum-ist-das-aendern-von-checked-ein-click.html)

Alallart 29. Jun 2023 14:46

Hä? Warum ist das Ändern von Checked ein Click?
 
Ich will statt mit drei RadioButtons eine Auswahl mit zwei CheckBoxen lösen. Gedacht ist das so: beide Checkboxen können abgewählt sein, dann kann einer von beiden ausgewählt sein. Wird einer einer von den beiden ausgewählt, muss natürlich der andere abgewählt werden. Theoretisch sollte das damit möglich sein:
Delphi-Quellcode:
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  CheckBox2.Checked := False;
end;

procedure TForm1.CheckBox2Click(Sender: TObject);
begin
  CheckBox1.Checked := False;
end;
Jetzt passiert aber etwas was ich nicht verstehe. Klicke ich auf CheckBox1, um es auszuwählen, wird in der Prozedur CheckBox2.Checked auf False gestellt. Das führt aber dazu, dass die Prozedur CheckBox2Click aufgerufen wird, und CheckBox1.Checked auf False stellt. Warum das denn?

Warum führt der Checked Code dazu, dass es als Click wahrgenommen wird?

Führe ich den Code durch eine Button Prozedur, passiert das nicht.

himitsu 29. Jun 2023 14:58

AW: Hä? Warum ist das Ändern von Checked ein Click?
 
Weil jemand vor über 20 Jahren dachte es wäre cool so.
Und nun bleibt es so, weil is halt so. :angle:




Einige haben sich über eine Ableitung, oder einen ClassHelper, da was gebaut. :zwinker:

Delphi-Quellcode:
//property CheckedNoClick: Boolean read GetCheckedNoClick write SetCheckedNoClick stored False;

procedure TMyCheckBox.SetCheckedNoClick(Value: Boolean);
var
  _Click, _Change: TNotifyEvent;
begin
  _Click := OnClick;
  _Change := Properties.OnChange;
  try
    OnClick            := nil;
    Properties.OnChange := nil;
    Checked            := Value;
  finally
    OnClick            := _Click;
    Properties.OnChange := _Change;
  end;
end;
OnChange ist für DevExpress (beim Delphi reicht OnClick)



[EDIT] Ich wusste doch da gab's nochwas, aber sah es vorhin natürlich nicht.
Delphi-Referenz durchsuchenClicksDisabled

PS: Hier im Forum suchenTCheckBox OnClick Checked

Uwe Raabe 29. Jun 2023 15:00

AW: Hä? Warum ist das Ändern von Checked ein Click?
 
Das ist nun mal das Standardverhalten.

Lösung 1 (quick-and-dirty): Du setzt das (allerdings protected) Property ClicksDisabled temporär auf True.
Lösung 2 (sauber aber aufwändig): Du verwendest zwei Actions, die einen gemeinsamen Status manipulieren bzw. überwachen.

Sherlock 29. Jun 2023 15:07

AW: Hä? Warum ist das Ändern von Checked ein Click?
 
So isses. Und das ist gemäß Doku sogar so gewollt
Zitat:

Hinweis: Wenn Sie den Wert der Eigenschaft Checked programmseitig ändern, wird das Ereignis OnClick des Kontrollkästchen-Steuerelements ausgelöst. Ändern Sie den Wert der Eigenschaft Checked nicht in der Ereignisbehandlungsroutine des Ereignisses OnClick, weil dies zu einem Deadlock führt.
Hat mich damals auch mal ein paar Tage näher an die Rente gebracht.

Sherlock

bcvs 29. Jun 2023 15:08

AW: Hä? Warum ist das Ändern von Checked ein Click?
 
Das OnClick einer Checkbox wird immer ausgelöst, wenn sich der Checked-Staus ändert, sei es durch Anklicken oder aus dem Programm heraus. Sollte vielleicht besser OnChecked heißen.

Ich mache es immer so. Ohne Actions oder ClassHelper oder Ableitungen
Delphi-Quellcode:
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  if not DoCheckBox1Click then
    exit;

  DoCheckBox2Click:=false;
  CheckBox2.Checked := False;
  DoCheckBox2Click:=true;
end;

procedure TForm1.CheckBox2Click(Sender: TObject);
begin
  if not DoCheckBox2Click then
    exit;

  DoCheckBox1Click:=false;
  CheckBox1.Checked := False;
  DoCheckBox1Click:=true;
end;
DoCheckBox1Click und DoCheckBox2Click natürlich irgenwo vorher sinnvoll auf true setzen.

Jasocul 29. Jun 2023 15:09

AW: Hä? Warum ist das Ändern von Checked ein Click?
 
Noch ein Q&D:
Du müsstest im Click-Event den Sender prüfen können. Kommt der von der falschen CheckBox führst du den Code nicht aus.
Falls es mit dem Sender nicht geht, müsste das ActiveControl vermutlich auch als Test möglich sein.
Nächste Möglichkeit:
Wenn die CheckBox1 geklickt wird, den Eventzeiger von CheckBox2 auf nil setzen, dann die CheckBox2 umsetzen. Anschließend wieder das Event zuweisen.

Das aktuelle Verhalten hat Vor- und Nachteile. Ich würde daher nicht grundsätzlich behaupten, dass es falsch ist.

Uwe Raabe 29. Jun 2023 15:14

AW: Hä? Warum ist das Ändern von Checked ein Click?
 
Genau dafür gibt es ja eben das ClicksDisabled. Das wird auch von den Actions so verwendet, wie dieser Code aus TButtonControl.ActionChange zeigt:
Delphi-Quellcode:
        // prevent generating Action.OnExecute when the control gets checked
        OldClicksDisabled := ClicksDisabled;
        ClicksDisabled := True;

        Self.Checked := Checked;

        ClicksDisabled := OldClicksDisabled;

dummzeuch 29. Jun 2023 16:11

AW: Hä? Warum ist das Ändern von Checked ein Click?
 
Zitat:

Zitat von Sherlock (Beitrag 1523951)
So isses. Und das ist gemäß Doku sogar so gewollt
Zitat:

Hinweis: Wenn Sie den Wert der Eigenschaft Checked programmseitig ändern, wird das Ereignis OnClick des Kontrollkästchen-Steuerelements ausgelöst. Ändern Sie den Wert der Eigenschaft Checked nicht in der Ereignisbehandlungsroutine des Ereignisses OnClick, weil dies zu einem Deadlock führt.

Naja "gewollt" ist übertrieben, eigentlich kann das keiner wirklich wollen - zumindest fällt mir kein Fall ein, wo das einen Vorteil hätte -, aber immerhin ist es dokumentiert.

himitsu 29. Jun 2023 16:22

AW: Hä? Warum ist das Ändern von Checked ein Click?
 
Es fing ja schon damit an, dass auch die nutzerseitige Änderung im OnClick ankommt, und es kein OnChange gab/gibt. (DevExpress hat bei seiner TcxCheckBox zusätzlich ein OnChange)
und da das "Click" somit eigenlich "Change" bedeutet, ist es "richtig", dass es beim Change auch klickt :angle2:

klaus schaaff 2. Jul 2023 11:29

AW: Hä? Warum ist das Ändern von Checked ein Click?
 
Hallo Delphi-PRAXiS,

vielleicht etwas OldSchool, aber das sollte auch noch funktionieren.

Delphi-Quellcode:

var
  DontChange: Boolean = False;

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  if DontChange = True then Exit;
  DontChange := True;
  try
    CheckBox2.Checked := False;
  finally
    DontChange := False;
  end;
end;

procedure TForm1.CheckBox2Click(Sender: TObject);
begin
  if DontChange = True then Exit;
  DontChange := True;
  try
    CheckBox1.Checked := False;
  finally
    DontChange := False;
  end;
end;
Besonders bei älteren Delphi-Versionen.


Liebe Grüße
Klaus Schaaff


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:11 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz