Autor Beitrag
Kralle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 65

Windows XP,Win7
Delphi 6, Turbo Delphi Pro, Delphi 7 Enterprise, Delphi XE2 Lazarus
BeitragVerfasst: Fr 22.07.11 23:59 
Guten Abend,

ich möchte, das wenn ich in einer CheckListBox einen Eintrag abwähle auch ein zweiter abgewählt wird.

Ich habe das so probiert:
ausblenden Delphi-Quelltext
1:
2:
3:
   CLB_middle.Checked[zeilennr2] := CLB_middle.Checked[zeilennr];

   CLB_middle.Checked[zeilennr] := CLB_middle.Checked[zeilennr2];


Aber die Checkboxen reagieren nur auf die oberste Zeile.

Wichtig ist aber, das egal ob Zeile 1 oder Zeile 2 abgewählt wird, die andere auch abgewählt wird.
Ich habe es auch mit
ausblenden Delphi-Quelltext
1:
2:
3:
4:
 If CLB_middle.Checked[zeilennr] = false then
  CLB_middle.Checked[zeilennr2] := false;
 If CLB_middle.Checked[zeilennr2] = false then
  CLB_middle.Checked[zeilennr] := false;

probiert, aber dann ist nach dem ersten abwählen Schluß und ich kann die Zeilen nicht mehr anwählen.

Was übersehe ich um diese Uhrzeit?

Gruß Heiko
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19341
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 23.07.11 10:25 
user profile iconKralle hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe das so probiert:
ausblenden Delphi-Quelltext
1:
2:
3:
   CLB_middle.Checked[zeilennr2] := CLB_middle.Checked[zeilennr];

   CLB_middle.Checked[zeilennr] := CLB_middle.Checked[zeilennr2];


Aber die Checkboxen reagieren nur auf die oberste Zeile.
Naja, zuerst wird die erste Zeile ausgeführt. Danach ist der Status der ersten in der zweiten drin.

Wenn dann die zweite Zeile ausgeführt wird, wird dieser Wert nur in die erste zurückgelegt...

user profile iconKralle hat folgendes geschrieben Zum zitierten Posting springen:
probiert, aber dann ist nach dem ersten abwählen Schluß und ich kann die Zeilen nicht mehr anwählen.
Naja, irgendwie musst du ja auch erst einmal einen einzeln aktivieren können. Mit deinem Code deaktivierst du schon den ersten sofort wieder.

Das Problem ist hier, dass du die Daten (was markiert ist) mit der Oberfläche durcheinanderwirfst. Denn so weißt du nicht welcher Eintrag geändert wurde. Wenn du aber bei einer Änderung abgleichst, was sich geändert hat, kannst du nur beim Abwählen den zweiten mitnehmen und ein Anwählen erlauben.

Oder du benutzt eine ordentliche Komponente wie die TVirtualStringTree, da gibt es das Ereigbnis OnChecking, in dem du das Markieren sogar direkt unterbinden kannst usw., aber vor allem bekommst du geliefert was sich eigentlich genau ändert. Also welcher Eintrag, ob er an- oder abgewählt wird, ...
Und danach in OnChecked bekommst du den Knoten ebenfalls geliefert.


Zuletzt bearbeitet von jaenicke am Sa 23.07.11 14:50, insgesamt 1-mal bearbeitet

Für diesen Beitrag haben gedankt: Kralle
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Sa 23.07.11 13:43 
Hab mir eben mal den Code von der CheckListBox angeguckt:

ausblenden 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:
//das hier wird aufgerufen, wenn sich der Zustand ändert
procedure TCheckListBox.ToggleClickCheck(Index: Integer);
var
  State: TCheckBoxState;
begin
  if (Index >= 0and (Index < Items.Count) and GetItemEnabled(Index) then
  begin
    State := Self.State[Index];
    case State of
      cbUnchecked:
        if AllowGrayed then State := cbGrayed else State := cbChecked;
      cbChecked: State := cbUnchecked;
      cbGrayed: State := cbChecked;
    end;
    Self.State[Index] := State;
    ClickCheck; //hier müsste man nur den Index mitübergeben
  end;
end;

//wird danach aufgerufen und ruft das Event auf
procedure TCheckListBox.ClickCheck;
begin
  if Assigned(FOnClickCheck) then FOnClickCheck(Self); //hier den Index mit übergeben
end;


Ich frage mich warum der Entwickler den Index nicht mit nach außen gereicht hat, da es wirklich naheliegend und einfach wäre... Leider ist Toggle private...man müsste also an die original-Datei ran und dort ändern, dann wirkt es sich aber auf ALLE deine Projekte aus

Edit:
Was man noch verantworten könnte, wäre das Toggle als protected zu setzen und dann davon zu erben, die Methode zu überschreiben und ein zusätzliches Event zu erstellen. Dann kannst du aber diese Klasse nur compilieren, wenn du die modifizierte Originaldatei hast (Problem nach Neuinstallation, fremden Rechner)...nicht wirklich schön.

Edit2:
Vielleicht wäre es doch am einfachsten/saubersten dir bei jedem OnClickCheck die zwei Werte, die dich interessieren, zwischenzuspeichern und beim nächsten mal zu gucken, welches sich verändert hat und das entsprechend andere zu setzen. Ein bool Array wäre da ja völlig ausreichend (als Gegenstück zu CheckListBox.Checked[]).

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)

Für diesen Beitrag haben gedankt: Kralle
Kralle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 65

Windows XP,Win7
Delphi 6, Turbo Delphi Pro, Delphi 7 Enterprise, Delphi XE2 Lazarus
BeitragVerfasst: Sa 23.07.11 14:45 
Moin,

user profile iconXion hat folgendes geschrieben Zum zitierten Posting springen:

Edit2:
Vielleicht wäre es doch am einfachsten/saubersten dir bei jedem OnClickCheck die zwei Werte, die dich interessieren, zwischenzuspeichern und beim nächsten mal zu gucken, welches sich verändert hat und das entsprechend andere zu setzen. Ein bool Array wäre da ja völlig ausreichend (als Gegenstück zu CheckListBox.Checked[]).


Das werde ich mal testen.
Danke, das Du Dir soviel Mühe gemacht hast und sogar den Quellcode der Orginalroutine nach einer Möglichkeit untersucht hast.

Gruß Heiko
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19341
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 23.07.11 14:46 
Aber wie gesagt: Die TVirtualStringTree kann viel mehr und liefert dir die Informationen auch direkt. Also warum nicht gleich die benutzen? :nixweiss:

Für diesen Beitrag haben gedankt: Kralle
Kralle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 65

Windows XP,Win7
Delphi 6, Turbo Delphi Pro, Delphi 7 Enterprise, Delphi XE2 Lazarus
BeitragVerfasst: Sa 23.07.11 14:47 
Hallo Sebastian,

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:

Das Problem ist hier, dass du die Daten (was markiert ist) mit der Oberfläche durcheinanderwirfst. Denn so weißt du nicht welcher Eintrag geändert wurde. Wenn du aber bei einer Änderung abgleichst, was sich geändert hat, kannst du nur beim Abwählen den zweiten mitnehmen und ein Anwählen erlauben.

Oder du benutzt eine ordentliche Komponente wie die [url]TVirtualStringTree[/url], da gibt es das Ereigbnis OnChecking, in dem du das Markieren sogar direkt unterbinden kannst usw., aber vor allem bekommst du geliefert was sich eigentlich genau ändert. Also welcher Eintrag, ob er an- oder abgewählt wird, ...
Und danach in OnChecked bekommst du den Knoten ebenfalls geliefert.

Ich werde mir die Tage mal die obige Komponente anschauen (Dein Link funktioniert nicht).

Gruß Heiko
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19341
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 23.07.11 14:51 
user profile iconKralle hat folgendes geschrieben Zum zitierten Posting springen:
(Dein Link funktioniert nicht).
Ups, korrigiert, ich meinte den:
www.delphi-gems.com/...;id=12&Itemid=38
Und eine Anleitung dazu:
www.delphi-treff.de/...uehrunginstallation/

Für diesen Beitrag haben gedankt: Kralle
Kralle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 65

Windows XP,Win7
Delphi 6, Turbo Delphi Pro, Delphi 7 Enterprise, Delphi XE2 Lazarus
BeitragVerfasst: Mo 25.07.11 07:36 
Moin,

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconKralle hat folgendes geschrieben Zum zitierten Posting springen:
(Dein Link funktioniert nicht).
Ups, korrigiert, ich meinte den:
www.delphi-gems.com/...;id=12&Itemid=38
Und eine Anleitung dazu:
www.delphi-treff.de/...uehrunginstallation/


Das ist aber ja eine Komponente um z.B. Verzeichnisbäume anzuzeigen.
Ich brauche nur eine Liste in der ich Einträge an- und abwählen kann.

Gruß Heiko
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19341
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 25.07.11 09:54 
user profile iconKralle hat folgendes geschrieben Zum zitierten Posting springen:
Das ist aber ja eine Komponente um z.B. Verzeichnisbäume anzuzeigen.
Ich brauche nur eine Liste in der ich Einträge an- und abwählen kann.
Das kann die Komponente genauso gut. Das ist quasi die tabellenlegende Baumknotensau. :mrgreen:

Für diesen Beitrag haben gedankt: Kralle, Regan
Kralle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 65

Windows XP,Win7
Delphi 6, Turbo Delphi Pro, Delphi 7 Enterprise, Delphi XE2 Lazarus
BeitragVerfasst: Di 09.08.11 20:05 
Moin,

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Das kann die Komponente genauso gut. Das ist quasi die tabellenlegende Baumknotensau. :mrgreen:


Ich habe mir die Anleitung durch gelesen und entschieden, das ich das für aktuelle Projekt erstmal nicht einsetzen werde.
Die Links werde ich mir aber bei Seite packen und vielleicht in der nächsten Ausbaustufe des Programmes darauf zurückkommen.
Danke, für die Hilfe.

Gruß Heiko
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Mi 10.08.11 16:30 
user profile iconKralle hat folgendes geschrieben Zum zitierten Posting springen:

Ich habe es auch mit
ausblenden Delphi-Quelltext
1:
2:
3:
4:
 If CLB_middle.Checked[zeilennr] = false then
  CLB_middle.Checked[zeilennr2] := false;
 If CLB_middle.Checked[zeilennr2] = false then
  CLB_middle.Checked[zeilennr] := false;

probiert, aber dann ist nach dem ersten abwählen Schluß und ich kann die Zeilen nicht mehr anwählen.


Einen Wahrheitswert auf false zu prüfen, ist zwar logisch nicht falsch, aber unelegant und wegen Compiler-Interna sogar in gewisser Weise falsch, (soll tatsächlich zu falschen Ergebnissen führen können) auch wenn der Fehler oder "Fehler" m.E. eindeutig beim Compiler liegt (interne Verarbeitung logischer Werte über Integervariablen). Dazu gab es schon Diskussionen. Eleganter und kürzer ist jedenfalls einfach: if not ...
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19341
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 10.08.11 16:49 
user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
Einen Wahrheitswert auf false zu prüfen, ist zwar logisch nicht falsch, aber unelegant und wegen Compiler-Interna sogar in gewisser Weise falsch, (soll tatsächlich zu falschen Ergebnissen führen können)
Der Vergleich mit False wird nicht fehlschlagen, da False tatsächlich immer gleich Null ist. Da alles andere aber als True gilt, egal welcher Wert, kann der Vergleich mit True fehlschlagen.
Hier habe ich mal ein kleines Beispiel gebastelt, wann es schief geht:
www.delphi-forum.de/....php?p=548760#548760
Mehr dazu steht hier:
www.delphi-treff.de/...olean-werten/page/4/
Und warum das auch vollkommen unlogisch ist:
www.delphi-forum.de/....php?p=560637#560637

user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
auch wenn der Fehler oder "Fehler" m.E. eindeutig beim Compiler liegt (interne Verarbeitung logischer Werte über Integervariablen)
True und False sind nur Konstanten für einen Wert. Wenn du damit vergleichst, kann da der Compiler doch nichts dafür, wenn das nicht das ist was du wolltest. ;-)
Man kann Programmierfehler eben nicht sinnvoll durch Compilermagic ausgleichen, da sonst der zusätzliche Code alles signifikant langsamer machen würde. Man könnte höchstens Warnungen einbauen oder so. Allerdings steht dieser Fehler nicht umsonst unter "Anfängerfehler" in diversen Tutorials usw. :zwinker:

Aber zu dem Thema gibt es in der Tat bereits genug Threads. :D