Recent

Author Topic: CheckListBox Status Persistence  (Read 4270 times)

greertr

  • Full Member
  • ***
  • Posts: 113
    • Virtual Pilot Dashboard
CheckListBox Status Persistence
« on: September 07, 2017, 12:47:10 pm »
Hi all,

Is there a way to ensure persistence of a checklist box each time an application is executed? 

For example, if a couple of boxes are checked, then next time the program is run, I want those boxes to still be checked.

thx in adv


minesadorada

  • Sr. Member
  • ****
  • Posts: 452
  • Retired
Re: CheckListBox Status Persistence
« Reply #1 on: September 07, 2017, 01:36:24 pm »
My suggestion:
If the application is run locally (i.e. not a web/network app) then you can store the checkbox state (as a bool value) in a config file in formOnClose, and read the values in at form OnLoad.
Use GetAppConfigFile function for the config file's name and location, and TINIFiles unit to read/write.

This is Windows and Linux compatible.
« Last Edit: September 07, 2017, 01:38:06 pm by minesadorada »
GPL Apps: Health MonitorRetro Ski Run
OnlinePackageManager Components: LazAutoUpdate, LongTimer, PoweredBy, ScrollText, PlaySound, CryptINI

greertr

  • Full Member
  • ***
  • Posts: 113
    • Virtual Pilot Dashboard
Re: CheckListBox Status Persistence
« Reply #2 on: September 07, 2017, 03:17:47 pm »
...umm realizing how ignorant of Lazarus I truly am  :-[

Well, I have the checklistbox1 saving an alpha character ('x'), but i can't get tp reload when i start the program again.

The Save code seems to work, I checked the xml file and did see the 'x' in there.

Code: Pascal  [Select][+][-]
  1. procedure TForm4.Button3Click(Sender: TObject);
  2. begin
  3.  
  4.   if Checklistbox1.Checked[0]
  5.     then form4.stringgrid1.cells[0,0] := 'x'
  6.     else form4.stringgrid1.cells[0,0] := '' ;
  7.  
  8.   if Checklistbox1.Checked[1]
  9.     then form4.stringgrid1.cells[1,0] := 'x'
  10.     else form4.stringgrid1.cells[1,0] := '' ;
  11.  
  12.   if Checklistbox1.Checked[2]
  13.     then form4.stringgrid1.cells[2,0] := 'x'
  14.     else form4.stringgrid1.cells[2,0] := '' ;
  15.  
  16.   if Checklistbox1.Checked[3]
  17.     then form4.stringgrid1.cells[3,0] := 'x'
  18.     else form4.stringgrid1.cells[3,0] := '' ;
  19.  
  20.     if Checklistbox1.Checked[4]
  21.     then form4.stringgrid1.cells[4,0] := 'x'
  22.     else form4.stringgrid1.cells[4,0] := '' ;
  23.  
  24.     if Checklistbox1.Checked[5]
  25.     then form4.stringgrid1.cells[5,0] := 'x'
  26.     else form4.stringgrid1.cells[5,0] := '' ;
  27.  
  28.     stringgrid1.SaveOptions := [soDesign,soPosition,soAttributes,soContent];
  29.     form4.StringGrid1.SaveToFile('trgtasks.xml');
  30.  
  31. end;  

But the Load code no worky...
Code: Pascal  [Select][+][-]
  1. procedure TForm4.FormCreate(Sender: TObject);
  2. begin
  3.   form4.StringGrid1.LoadFromFile('trgtasks.xml');
  4.  
  5.   if (form4.stringgrid1.cells[0,0] = 'x')
  6.     then  Checklistbox1.Checked[0];
  7. end;  

The xml snippet...
Code: Pascal  [Select][+][-]
  1.     <content>
  2.       <cells cellcount="1">
  3.         <cell1 column="0" row="0" text="x"/>
  4.       </cells>
  5.     </content>
« Last Edit: September 07, 2017, 04:46:57 pm by greertr »

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: CheckListBox Status Persistence
« Reply #3 on: September 07, 2017, 05:58:16 pm »
A very simple-minded approach would be something like this.
Drop a checklistbox on a form in a new Lazarus project, add a few items to it, and then add OnCreate and OnClose form handlers as follows:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, CheckLst;
  9.  
  10. type
  11.  
  12.   TForm1 = class(TForm)
  13.     CheckListBox1: TCheckListBox;
  14.     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  15.     procedure FormCreate(Sender: TObject);
  16.   private
  17.     const
  18.       ChkLBFileDataName = 'checklistbox.dat';
  19.     procedure SaveListBoxSettings(aChkLB: TCheckListBox);
  20.     procedure LoadCheckListBoxSettings(aChkLB: TCheckListBox);
  21.   end;
  22.  
  23. var
  24.   Form1: TForm1;
  25.  
  26. implementation
  27.  
  28. {$R *.lfm}
  29.  
  30. procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  31. begin
  32.   SaveListBoxSettings(CheckListBox1);
  33. end;
  34.  
  35. procedure TForm1.FormCreate(Sender: TObject);
  36. begin
  37.   LoadCheckListBoxSettings(CheckListBox1);
  38. end;
  39.  
  40. procedure TForm1.LoadCheckListBoxSettings(aChkLB: TCheckListBox);
  41. var
  42.   sl: TStringList;
  43.   i: Integer = 0;
  44.   s: String;
  45. begin
  46.   if Assigned(aChkLB) and FileExists(ChkLBFileDataName) then begin
  47.     sl:=TStringList.Create;
  48.     try
  49.       sl.LoadFromFile(ChkLBFileDataName);
  50.       Assert(sl.Count=aChkLB.Items.Count,'CheckListbox has changed since last data saved');
  51.       for s in sl do begin
  52.         case Length(s) of
  53.           0: aChkLB.Checked[i]:=False;
  54.           else aChkLB.Checked[i]:=True;
  55.         end;
  56.         Inc(i);
  57.       end;
  58.     finally
  59.       sl.Free;
  60.     end;
  61.   end;
  62. end;
  63.  
  64. procedure TForm1.SaveListBoxSettings(aChkLB: TCheckListBox);
  65. var
  66.   sl: TStringList;
  67.   i: Integer;
  68.   s: String;
  69. begin
  70.   if Assigned(aChkLB) then begin
  71.     sl:=TStringList.Create;
  72.     try
  73.       for i:=0 to aChkLB.Items.Count-1 do begin
  74.         if aChkLB.Checked[i] then
  75.           s:='x'
  76.         else s:='';
  77.         sl.Add(s);
  78.       end;
  79.       sl.SaveToFile(ChkLBFileDataName);
  80.     finally
  81.       sl.Free;
  82.     end;
  83.   end;
  84. end;
  85.  
  86. end.

greertr

  • Full Member
  • ***
  • Posts: 113
    • Virtual Pilot Dashboard
Re: CheckListBox Status Persistence
« Reply #4 on: September 07, 2017, 07:34:04 pm »
Thx a lot howardpc!  The example works perfectly and the code appears to be something I can work with and adapt  8-)
« Last Edit: September 07, 2017, 10:04:50 pm by greertr »

PatBayford

  • Full Member
  • ***
  • Posts: 125
Re: CheckListBox Status Persistence
« Reply #5 on: September 07, 2017, 10:05:45 pm »
In Delhi this would have been handled by the IDE, using the built-in persistence models. This was sometimes a real nuisance if you did not want the data to be persistent! However, I don't think I ever used a CheckListBox for real, so it's behaviour may have been different.
Do I assume that the default Lazarus behaviour is different?
And if so, why not just use the equivalent of SaveComponent/LoadComponent?
The actual methods are :-
TStream.WriteComponent( Instance: TComponent);
Description
WriteComponent writes the published properties of Instance to the stream, so they can later be read with TStream.ReadComponent. This method is intended to be used by an IDE, to preserve the state of a form or datamodule as designed in the IDE.
WriteComponent simply calls WriteDescendant with Nil ancestor.

AND
TStream.ReadComponent        Reads component data from a stream

« Last Edit: September 08, 2017, 02:11:48 am by PatBayford »
Lazarus 1.8.0 FPC 3.0.2 SVN 56594 Windows 10 64bit (i386-win32-win32/win64)

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: CheckListBox Status Persistence
« Reply #6 on: September 08, 2017, 09:27:06 am »
...why not just use the equivalent of SaveComponent/LoadComponent?
The actual methods are :-
TStream.WriteComponent( Instance: TComponent);
AND
TStream.ReadComponent       

There are nearly always multiple ways to accomplish a programming task. ReadComponent/WriteComponent is certainly a good way, though it obviously creates a slightly bigger data file (about 200 bytes for all published properties) than a customised solution that saves only the boolean data the OP asked about (whose file size is typically about 10 bytes depending on the number of checkbox items).

greertr

  • Full Member
  • ***
  • Posts: 113
    • Virtual Pilot Dashboard
Re: CheckListBox Status Persistence
« Reply #7 on: September 08, 2017, 02:17:53 pm »
i got the above problem resolved with howard pc's assistance, and now for the next issue - if all the boxes are checked, i want an image to show (it does), and then if a box is later unchecked, i want the image to vanish.  I've almost got it working, but when i uncheck a box, the image still shows

Code: Pascal  [Select][+][-]
  1. procedure TForm13.Button2Click(Sender: TObject);
  2. var
  3.  i,j: integer;        // Update button routine
  4. begin
  5.     SaveListBoxSettings(CheckListBox1);
  6.     LoadCheckListBoxSettings(CheckListBox1);
  7.     i := 0;
  8.     j := 0;
  9.     for i := 0 to listbox1.count - 1 do
  10.     begin
  11.       if checklistbox1.checked[i] then inc (j);
  12.       if (j = listbox1.count) then form1.image2.visible := true;
  13.       if (j = listbox1.count) then form1.Label8.visible := true;
  14.       if (j < listbox1.count) then form1.image2.visible := false;
  15.       if (j < listbox1.count) then form1.Label8.visible := false;
  16.     end;
  17. end;  

« Last Edit: September 08, 2017, 02:35:19 pm by greertr »

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: CheckListBox Status Persistence
« Reply #8 on: September 08, 2017, 02:36:03 pm »
1) check for the count after the loop has finished counting them

Code: Pascal  [Select][+][-]
  1.     procedure TForm13.Button2Click(Sender: TObject);
  2.     var
  3.      i,j: integer;
  4.     begin
  5.         SaveListBoxSettings(CheckListBox1);
  6.         LoadCheckListBoxSettings(CheckListBox1);
  7.         i := 0;
  8.         j := 0;
  9.         for i := 0 to listbox1.count - 1 do
  10.         begin
  11.           if checklistbox1.checked[i] then inc (j);
  12.           //if not checklistbox1.checked[i] then dec (j);
  13.         end;
  14.         if (j = listbox1.count) then form1.image2.visible := true;
  15.         if (j < listbox1.count) then form1.image2.visible := false;
  16.         if (j = listbox1.count) then form1.Label8.visible := true;
  17.         if (j < listbox1.count) then form1.Label8.visible := false;
  18.         //invalidate;
  19.     end;  
2) You can simplify the code to
Code: Pascal  [Select][+][-]
  1.         form1.image2.visible := (j = listbox1.count);
  2.         form1.Label8.visible := (j = listbox1.count);
  3.  
if it still does not hide the image and label then
1) search your code if you activate the image somewhere else or you have the same image in an other tImage etc.
2) uncomment the invalidate call on my code and see if that helps.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

fred

  • Full Member
  • ***
  • Posts: 201
Re: CheckListBox Status Persistence
« Reply #9 on: September 08, 2017, 02:36:46 pm »
You can try this:

Code: Pascal  [Select][+][-]
  1. j := 0;
  2. for i := 0 to listbox1.count - 1 do
  3. begin
  4.   if checklistbox1.checked[i]
  5.   then inc (j);
  6. end;
  7. // you don't need a begin end because there is only one statement in the for loop but it might be more clear
  8. // you could name j as checked_count to make it more clear
  9.  
  10. form1.image2.visible := (j = listbox1.count);
  11. form1.Label8.visible := form1.image2.visible;

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: CheckListBox Status Persistence
« Reply #10 on: September 08, 2017, 02:38:10 pm »
What is the relationship between listbox1 and checkListbox1?

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: CheckListBox Status Persistence
« Reply #11 on: September 08, 2017, 02:40:34 pm »
What is the relationship between listbox1 and checkListbox1?
lol, and I missed too.  :-[ good catch!
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

greertr

  • Full Member
  • ***
  • Posts: 113
    • Virtual Pilot Dashboard
Re: CheckListBox Status Persistence
« Reply #12 on: September 08, 2017, 02:42:53 pm »
none, i was just using code from another posting...

guess i thought list box would do the trick

laz seems fuzzy to me at times lol

i  changed list box to checklistbox and it works correctly now -- thx
« Last Edit: September 08, 2017, 02:44:58 pm by greertr »

 

TinyPortal © 2005-2018