AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Hä? Warum ist das Ändern von Checked ein Click?
Thema durchsuchen
Ansicht
Themen-Optionen

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

Ein Thema von Alallart · begonnen am 29. Jun 2023 · letzter Beitrag vom 5. Jul 2023
Antwort Antwort
Seite 1 von 3  1 23      
Alallart

Registriert seit: 8. Dez 2015
153 Beiträge
 
#1

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

  Alt 29. Jun 2023, 14:46
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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#2

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

  Alt 29. Jun 2023, 14:58
Weil jemand vor über 20 Jahren dachte es wäre cool so.
Und nun bleibt es so, weil is halt so.




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

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
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (29. Jun 2023 um 15:17 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.009 Beiträge
 
Delphi 12 Athens
 
#3

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

  Alt 29. Jun 2023, 15:00
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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming

Geändert von Uwe Raabe (29. Jun 2023 um 15:12 Uhr) Grund: Inverse Logik!
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.763 Beiträge
 
Delphi 11 Alexandria
 
#4

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

  Alt 29. Jun 2023, 15:07
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
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann

Geändert von Sherlock (29. Jun 2023 um 15:10 Uhr)
  Mit Zitat antworten Zitat
bcvs

Registriert seit: 16. Jun 2011
668 Beiträge
 
Delphi 12 Athens
 
#5

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

  Alt 29. Jun 2023, 15:08
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.
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.338 Beiträge
 
Delphi 11 Alexandria
 
#6

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

  Alt 29. Jun 2023, 15:09
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.
Peter
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.009 Beiträge
 
Delphi 12 Athens
 
#7

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

  Alt 29. Jun 2023, 15:14
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;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.468 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

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

  Alt 29. Jun 2023, 16:11
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.
Thomas Mueller
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#9

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

  Alt 29. Jun 2023, 16:22
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
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
klaus schaaff

Registriert seit: 25. Jul 2009
24 Beiträge
 
#10

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

  Alt 2. Jul 2023, 11:29
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
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:57 Uhr.
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