AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TVCheckListbox und TStringList

Ein Thema von Blackpit · begonnen am 6. Jul 2019 · letzter Beitrag vom 7. Jul 2019
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#11

AW: TVCheckListbox und TStringList

  Alt 7. Jul 2019, 10:18
myKat

Wie soll er auch was anzeigen, wenn du keine Variable zu weist? Aber geht er denn in den if-Zweig rein?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Blackpit

Registriert seit: 27. Feb 2019
77 Beiträge
 
#12

AW: TVCheckListbox und TStringList

  Alt 7. Jul 2019, 11:30
Also, der Find funktioniert auch wenn er den Wert des Ausdrucks nicht anzeigt ('Nicht verfügbarer Wert'), wieso weshalb wissen die Delphi-Götter
Die andere Frage beantworte ich mir selbst, sie agieren identisch.
Das Problem lag woanders, der gezeigte Code erfüllt allerdings noch nicht mein Vorhaben.

Geändert von Blackpit ( 7. Jul 2019 um 11:32 Uhr)
  Mit Zitat antworten Zitat
Rolf Frei

Registriert seit: 19. Jun 2006
629 Beiträge
 
Delphi 11 Alexandria
 
#13

AW: TVCheckListbox und TStringList

  Alt 7. Jul 2019, 12:26
as nicht, die Liste aktuell zu halten hier mein Versuch:
Delphi-Quellcode:
    begin
        myLst:= TCheckListbox(Sender).Name;
       if not assigned(myselection) then myselection := TStringList.create; //myselection.clear beim speichern
        begin
        myselection.Sort;
        TCheckListbox(Sender).Sorted := True;
          for i := TCheckListbox(Sender).Count-1 downto 0 do
// if TCheckListbox(Sender).Checked[i] then
          if TCheckListbox(Sender).State[i] = cbChecked then
            begin
              if not (myselection.Find(TCheckListbox(Sender).Items[i],myKat)) then myselection.Add(TCheckListbox(Sender).Items[i]);
            end
            else
            if (myselection.Find(TCheckListbox(Sender).Items[i],myKat)) and (TCheckListbox(Sender).State[i] = cbUnChecked) then
                  myselection.Delete(TCheckListbox(Sender).ItemIndex);
        end;
    end;
Was mach ich falsch?
1. Wieso sortierst du myselection? Sehe da keinen Sinn und Bedarf darin. Nutze IndexOf anstelle von Find.
2. myselection ist wohl ein Feld deiner Form. Richtig? Versuche dich an di gängigen Namen/Formatregeln von Delphi anzupassen, damit die Wartung deinss Programms später mal einfacher wird. Verwende daher für Object-Felder das Format Fxxx. (FMySelection würde ich es nennen) So siehst du sofort im Code, dass das eine Object-Feldvariable ist.
3. Abfage auf Checked reicht hier, wenn deine Checkboxen nur True/False haben können. Wenn du noch den 3. Status (grayed) hast, wirst du State abfragen müssen. Soweit die Antwort wieso es Checked und State gibt.
4. Wenn du nur ein Clear beim Speichern machst, fehlt dir noch ein Free der Stringliste irgendwo. Das gehört in das OnDestroy Event der Form oder noch besser in einen überschriebenen Destructor deiner Form.

Habe dir mal den Code so angepasst, wie ich das machen würde:

Delphi-Quellcode:
var
  StrIdx: Integer;
begin
        // myLst:= TCheckListbox(Sender).Name; ???
        if not Assigned(FMySelection) then
          FMySelection := TStringList.Create; //FMySelection.clear beim speichern
        // begin <- unnötig!
        //myselection.Sort; // wofür?
        //TCheckListbox(Sender).Sorted := True; // wofür?
          for i := 0 to TCheckListbox(Sender).Count-1 do
          begin
            StrIdx := FMySelection.IndexOf(TCheckListbox(Sender).Items[i]);
            if TCheckListbox(Sender).Checked[i] then
            begin
              if StrIdx = -1 then // Text nicht vorhanden
                FMySelection.Add(TCheckListbox(Sender).Items[i]);
            end
            // Checked muss hier nicht abgefragt werden, da das durch das if/else bereits geregelt ist.
            else if (StrIdx <> -1) then
            begin
              FMySelection.Delete(StrIdx);
            end;
          end;
end;

Geändert von Rolf Frei ( 7. Jul 2019 um 12:37 Uhr)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.415 Beiträge
 
Delphi 7 Professional
 
#14

AW: TVCheckListbox und TStringList

  Alt 7. Jul 2019, 12:28
Zitat von Delphihilfe:
Mit Checked stellen Sie fest, ob eine Schaltfläche markiert ist.
Zitat von Delphihilfe:
State gibt für jedes Element im Array Items an, ob das entsprechende Kontrollkästchen aktiviert (cbChecked) oder deaktiviert (cbUnchecked) ist oder ob es grau dargestellt wird (cbGrayed).

State kombiniert die von der booleschen Eigenschaft Checked und der booleschen Eigenschaft ItemEnabled bereitgestellten Informationen:

Wenn für Checked der Wert true gilt, hat State den Wert cbChecked. (Wenn Checked jedoch false ist, kann State entweder den Wert cbUnchecked oder den Wert cbGrayed haben.)
Wenn State cbGrayed ist, hat ItemEnabled false. (ItemEnabled kann aber auch false sein, wenn State den Wert cbUnchecked oder cbChecked hat.)
Delphi-Quellcode:
var
  myCheckLst : TCheckListbox;
  myLst : String;
  myKat : Integer;
begin
  if Sender is TCheckListbox then begin
    myCheckLst := TCheckListbox(Sender);
    myLst := myCheckLst.Name; // Wird das für irgendwas benötigt?
    // Bitte Luckies Kommentar dazu beachten und entsprechend umsetzen.
    if not assigned(myselection) then myselection := TStringList.create; // myselection.clear beim speichern
      myselection.Sort;
      myCheckLst.Sorted := True;
      for i := myCheckLst.Count - 1 downto 0 do begin
        if myCheckLst.Checked then begin
          if not (myselection.Find(myCheckLst.Items[i],myKat)) then myselection.Add(myCheckLst.Items[i]);
        end else begin
          // Wir suchen also in myselection die Zeichenfolge aus Items[i]
          if myselection.Find(myCheckLst.Items[i],myKat) then begin
            // und wenn wir die gefunden haben, löschen wir in myselection den Eintrag,
            // der die Position in myselection hat, die dem aktuell ausgewählten Eintrag aus myCheckLst entspricht?
            // Das ist dann so eine Art Zufallsgenerator, aber bestimmt nicht im Sinne des Erfinders.
            // myselection.Delete(myCheckLst.ItemIndex);
            // Könnte da nicht eher dashier zielführend sein, schließlich haben wir das ja gerade per Find ermittelt?
            myselection.Delete(myKat);
          end;
        end;
      end;
    end;
  end else begin
    // Sinnvolle Fehlermeldung ausgeben, wenn das Ereignis für was anderes als 'ne TCheckListbox aufgerufen wird.
  end;
end;
  Mit Zitat antworten Zitat
Rolf Frei

Registriert seit: 19. Jun 2006
629 Beiträge
 
Delphi 11 Alexandria
 
#15

AW: TVCheckListbox und TStringList

  Alt 7. Jul 2019, 12:50
Noch eine Ergänzung:

Wieso willst du diese Liste ständig aktuell halten, wenn du sie nur beim Speichern benötigst? Es würde doch reichen, die Liste jeweils komplett neu zu laden, also am Anfang ein Clear und dann eine simple for/next Schlaufe. Du machst dir da das Leben irgendwie viel zu umständlich. Es gibt keinen Grund die Liste zu bearbeiten. Das ganze würde wohl sogar um einiges schneller ablaufen, wenn du da keine Suchoperationen nutzen musst. Also mach doch einfach das oder gib soagr ein Resultat retour, das du dann 1:1 direkt in die DB schreiben kannst, ohne dass du beim Speichern noch die StringList verarbeten musst:


Delphi-Quellcode:
procedure TForm1.FillMySelection(const ACheckListbox: TCheckListbox);
var
  StrIdx: Integer;
begin
  if not Assigned(FMySelection) then
    FMySelection := TStringList.Create
  else
    FMySelection.Clear;

  for i := 0 to ACheckListbox.Count-1 do
    if ACheckListbox.Checked[i] then
      FMySelection.Add(ACheckListbox.Items[i]);
end;

Geändert von Rolf Frei ( 7. Jul 2019 um 12:56 Uhr)
  Mit Zitat antworten Zitat
Blackpit

Registriert seit: 27. Feb 2019
77 Beiträge
 
#16

AW: TVCheckListbox und TStringList

  Alt 7. Jul 2019, 13:24
Noch eine Ergänzung:

Wieso willst du diese Liste ständig aktuell halten, wenn du sie nur beim Speichern benötigst? ...
Das liegt an den Gegebenheiten des Projektes aber das ist ein anderes Thema. Das DM wurde geändert und um die Funktionalität beizubehalten bin ich auf dese Lösung gekommen. Das Formular wird mit Berechtigungsabfragen in den Bearbeitungsmodus geschaltet, bis zum speichern können beliebig Veränderungen vorgenommen werden.
Deinen Gedanken hatte ich auch schon, das Problem ist, dass die Daten aus einer Abfrage auf 6 Listenfelder anhand von Ausprägungen verteilt werden. Ich möchte auch die Einträge in der Tabelle nicht bei jeder Änderung Löschen und neu anlegen sondern nur gelöschte entfernen und neue hinzufügen. Daher die Idee mit der aktualisierten Liste.

@Delphi.Narium & @Rolf Frei
Danke für das lösen meines Knotens und die Empfehlungen, auf sowas habe ich gehofft

Geändert von Blackpit ( 7. Jul 2019 um 13:33 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 01:16 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