Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi TCheckListBox.items.checked[n] alle auf einmal setzen? (https://www.delphipraxis.net/195962-tchecklistbox-items-checked%5Bn%5D-alle-auf-einmal-setzen.html)

alleinherrscher 11. Apr 2018 10:25

TCheckListBox.items.checked[n] alle auf einmal setzen?
 
Hi@all.

Ich habe einen TTabControl. Jedes darin befindliche Tab soll andere Einträge in einer TCheckListBox anzeigen. Der Nutzer kann per Mausklick den die Haken bei den Einträgen der TCheckListBox entfernen oder setzen. Beim Wechsel zwischen Tabs müssen alle TCheckListBox.items.checked[n] für die entsprechenden Einträge wiederhergestellt werden.


Für jedes Tab habe ich ein boolsches Array, in welchem gespeichert ist, welcke Einträge "checked" sind und welche "unchecked" sind. Wie kann ich nun der TCheckListBox diese Information "schnell" übergeben? Seriell mit folgendem Code dauert dies eine halbe Ewigkeit, da nach jeder Änderung der Checked Property neu gezeichnet wird und die Variante halte ich für sehr unschön:

Delphi-Quellcode:
for n:=0 to length(CheckedMask)-1 do
   CheckListBox.checked[n]:=CheckedMask[n];
Aber ich habe weder im Forum, noch in der Delphi Hilfe eine Möglichkeit gefunden, den "checked-state" mehrer Einträge parallel zu setzen.

Hat jemand eine Idee?

Besten Gruß und vielen lieben Dank!

//edit: Tippfehler im Delphi-Quelltext behoben, danke an KodeZwerg, s. Beitrag nr. 6 und 7.

KodeZwerg 11. Apr 2018 12:42

AW: TCheckListBox.items.checked[n] alle auf einmal setzen?
 
Ich habe es gerade mal ausprobiert und stelle keine Neuzeichnungen fest.
Ich hab 50 Einträge in eine CheckListbox abgelegt und so den Checked-Wert verändert:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i : Integer;
begin
 for i := 0 to CheckListBox1.Items.Count-1 do
 begin
  CheckListBox1.Checked[i] := not CheckListBox1.Checked[i];
 end;
end;

juergen 11. Apr 2018 12:45

AW: TCheckListBox.items.checked[n] alle auf einmal setzen?
 
Hallo,

bezügl. Performance:
hilft hier evtl. ein
Delphi-Quellcode:
  try
    CheckListBox.Items.BeginUpdate;
    for n := 0 to length(CheckedMask) - 1 do
      CheckListBox.Checked[n] := CheckedMask[n];
  finally
    CheckListBox.Items.EndUpdate;
  end;

KodeZwerg 11. Apr 2018 13:05

AW: TCheckListBox.items.checked[n] alle auf einmal setzen?
 
Für "CheckListBox.Checked[X] := True/False" Variante braucht man kein Begin/EndUpdate da Einträge nicht verändert werden, nur die Box, oder irre ich mich?

alleinherrscher 11. Apr 2018 13:12

AW: TCheckListBox.items.checked[n] alle auf einmal setzen?
 
Zitat:

Zitat von KodeZwerg (Beitrag 1398796)
Für "CheckListBox.Checked[X] := True/False" Variante braucht man kein Begin/EndUpdate da Einträge nicht verändert werden, nur die Box, oder irre ich mich?

Korrekt, das habe ich schon versucht und das BeginUpdate funktioniert hier leider nicht. Das liegt daran meines Erachtens daran, dass im Quelltext (VCL.CheckLst) in der verantwortlichen Routine "SetState" ein "InvalidateCheck" aufgerufen wird, der via "UpdateWindow" irgendwie jedesmal alles neu zeichnet... Ich kann jedenfalls fast dabei zusehen, wie die Haken in der Liste der Reihe nach gesetzt werden (bei ca. 150 Einträgen).

Bisher habe ich herausgefunden, dass TListView die gleichen Funktionalität bereitstellen kann, aber hierbei eher noch langsamer arbeitet... Sehr komisch...

KodeZwerg 11. Apr 2018 13:19

AW: TCheckListBox.items.checked[n] alle auf einmal setzen?
 
Zitat:

Zitat von alleinherrscher (Beitrag 1398755)
CheckListBox.items[n].checked:=CheckedMask[n];

Da nimm CheckListBox.Checked[n] := CheckedMask[n];
Dein Aufruf über items[].checked löst ein Neuzeichnen aus, bin ich fast fest von überzeugt.

Uwe Raabe 11. Apr 2018 13:25

AW: TCheckListBox.items.checked[n] alle auf einmal setzen?
 
Zitat:

Zitat von KodeZwerg (Beitrag 1398800)
Dein Aufruf über items[].checked löst ein Neuzeichnen aus, bin ich fast fest von überzeugt.

Es gibt gar kein CheckListBox.Items.Checked, da Items vom Typ TStrings ist. Das Neuzeichnen wird in TCheckListBox.SetChecked ausgelöst.

Oder reden wir hier nicht über VCL?

alleinherrscher 11. Apr 2018 13:32

AW: TCheckListBox.items.checked[n] alle auf einmal setzen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von KodeZwerg (Beitrag 1398800)
Da nimm CheckListBox.Checked[n] := CheckedMask[n];
Dein Aufruf über items[].checked löst ein Neuzeichnen aus, bin ich fast fest von überzeugt.

Sorry, das war nur ein Tippfehler, items[].checked gibt es gar nicht, verwende natürlich CheckListBox.Checked. Wird meiner Meinung nach trotzdem neugezeichnet. Ich bin einen Schritt weiter. Das Parent der CheckListBox hat die Eigenschaft Doublebuffered auf true gesetzt. Entfernt man diese Option, wird das Verhalten der CheckListBox deutlich schneller. s. Anhang mit langsamer Version.

Das ist so schon mal besser, ich könnte mir aber vorstellen, dass es bei Fällen mit mehr als 150 Einträgen immer noch ein ähnliches Problem geben könnte. Aber vermutlich gibts hier keine bessere Möglichkeit, als alle Checkboxen einzeln zu setzen.

Zitat:

Zitat von Uwe Raabe
Das Neuzeichnen wird in TCheckListBox.SetChecked ausgelöst.

Oder reden wir hier nicht über VCL?

TCheckListBox.SetChecked kennt mein Delphi XE2 (noch) nicht? Wir reden über VCL.

Uwe Raabe 11. Apr 2018 13:41

AW: TCheckListBox.items.checked[n] alle auf einmal setzen?
 
Zitat:

Zitat von alleinherrscher (Beitrag 1398806)
ich könnte mir aber vorstellen, dass es bei Fällen mit mehr als 150 Einträgen immer noch ein ähnliches Problem geben könnte.

Das ist nicht unbedingt so. Vor dem UpdateWindow wird ja gezielt der Bereich der CheckBox per InvalidateRect für das Neuzeichnen angemeldet. Das Ändern nicht-sichtbarer Einträge sollten dabei auch kein Neuzeichnen auslösen.

KodeZwerg 11. Apr 2018 13:43

AW: TCheckListBox.items.checked[n] alle auf einmal setzen?
 
[Edit]Quarks[/Edit]
Ich habe mal in dein Projekt geschaut, eine schnellere Variante kenne ich auch nicht.
Wenn es Dir um Zeitersparniss in vielen CheckListBoxen geht, würd ich für jede eine CheckListBox nutzen, somit entfällt der Zeitraubende Faktor beim neu befüllen.
Ich hatte Anfangs gedacht das CheckListBoxen pro Tab die gleichen sind, nur halt anders markiert/gecheckt werden sollen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:50 Uhr.
Seite 1 von 2  1 2      

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