Recent

Author Topic: Tchecklistbox question  (Read 1767 times)

rwebb616

  • Full Member
  • ***
  • Posts: 133
Tchecklistbox question
« on: May 19, 2021, 04:18:57 am »
Is there a way to differenciate between the user clicking the checkbox vs just selecting something in the list? 

I am using a checklist box right now and I put a on-click procedure to make the selections easier so if you click any item it will reverse the checked state of the item.  The problem is if I click on the checkbox itself it will for example turn on and then back off or off and then back on depending on it's state because on itemclick is running as is on click.

Any way to tell if it's an item click vs selection?
Rich

Handoko

  • Hero Member
  • *****
  • Posts: 5154
  • My goal: build my own game engine using Lazarus
Re: Tchecklistbox question
« Reply #1 on: May 19, 2021, 04:39:51 am »
I put a on-click procedure to make the selections easier so if you click any item it will reverse the checked state of the item.

You don't need to write code for the OnClick event to reverse the state. TCheckListBox will do it automatically for you.

Or maybe I didn't fully understand your explanation.

Can you explain more or perhaps provide a simplified demo that can show us the issue?

rwebb616

  • Full Member
  • ***
  • Posts: 133
Re: Tchecklistbox question
« Reply #2 on: May 19, 2021, 04:47:27 am »
I'm sorry ... I wasn't clear..

I need to check these relatively fast and having to have the mouse directly on the checkbox was problematic so I had coded the on-click event to check or uncheck the box so all I had to do was click the item rather than being right on the checkbox.. but then I had the unintended behavior that when I DO click the checkbox it reverses whatever state so if I click to check it, it checks with the item selection event and then the checkbox unchecks because the checkbox was clicked. 

I just got it sorted though .. Also I forgot to mention that I can only select up to 6 items.  I did this:
Code: Pascal  [Select][+][-]
  1. procedure TfMainForm.clbCategoriesClick(Sender: TObject);
  2. var
  3.   index:integer;
  4.   i:integer;
  5.   checked:integer;
  6. begin
  7.   checked:=0;
  8.   index := clbcategories.itemindex;
  9.   clbCategories.Checked[index]:=not clbCategories.Checked[index];
  10.   for i:=0 to clbcategories.Count -1 do begin
  11.     if clbCategories.Checked[i] then inc(checked);
  12.   end;
  13.   if checked > options.maxcategories then begin
  14.   MessageDlg('Error','You can only select up to ' + options.maxcategories.tostring + ' categories!',mtError,[mbOK],'');
  15.   if clbCategories.checked[Index] then
  16.     clbCategories.Checked[Index]:=not clbCategories.checked[Index];
  17.   end;
  18. end;  

and I assigned this to two events - onclick and onclickcheck.  Because it runs the same code the checkbox reverses state I guess 3 times.  Once for the actual check being clicked, then once for each event. Ultimately it ends up in the state I want it to be in so now I can click either the checkbox or the item and it will limit me to 6 categories.

Rich

Handoko

  • Hero Member
  • *****
  • Posts: 5154
  • My goal: build my own game engine using Lazarus
Re: Tchecklistbox question
« Reply #3 on: May 19, 2021, 05:05:15 am »
I tested your code on both Windows and GTK2, I saw the problem. That issue does not happen on Linux GTK2.

Give me some time, I am working on it.

rwebb616

  • Full Member
  • ***
  • Posts: 133
Re: Tchecklistbox question
« Reply #4 on: May 19, 2021, 05:10:56 am »
I tested your code on both Windows and GTK2, I saw the problem. That issue does not happen on Linux GTK2.

Give me some time, I am working on it.

The code I posted is actually working for what I'm doing - or do you mean the original problem I posted about?

Rich

Handoko

  • Hero Member
  • *****
  • Posts: 5154
  • My goal: build my own game engine using Lazarus
Re: Tchecklistbox question
« Reply #5 on: May 19, 2021, 05:21:38 am »
The code you posted has problem on Win7 but it worked perfectly on Ubuntu Mate GTK2.

Here is my workaround, which quickly tested on both Linux and Windows:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   SysUtils, Forms, Dialogs, CheckLst;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     CheckListBox1: TCheckListBox;
  16.     procedure CheckListBox1Click(Sender: TObject);
  17.     procedure CheckListBox1ClickCheck(Sender: TObject);
  18.   end;
  19.  
  20. var
  21.   Form1: TForm1;
  22.  
  23. implementation
  24.  
  25. {$R *.lfm}
  26.  
  27. { TForm1 }
  28.  
  29. procedure TForm1.CheckListBox1Click(Sender: TObject);
  30. const
  31.   MaxCategories = 3;
  32. var
  33.   Index:   Integer;
  34.   i:       Integer;
  35.   Checked: integer;
  36. begin
  37.   Index   := CheckListBox1.ItemIndex;
  38.   Checked := 0;
  39.   CheckListBox1.Checked[Index] := not CheckListBox1.Checked[Index];
  40.   for i := 0 to CheckListBox1.Count-1 do
  41.     if CheckListBox1.Checked[i] then Inc(Checked);
  42.   if Checked > MaxCategories then begin
  43.     MessageDlg('Error', 'You can only select up to ' + MaxCategories.ToString +
  44.       ' categories!', mtError, [mbOK], '');
  45.     if CheckListBox1.Checked[Index] then
  46.       CheckListBox1.Checked[Index] := not CheckListBox1.Checked[Index];
  47.   end;
  48. end;
  49.  
  50. procedure TForm1.CheckListBox1ClickCheck(Sender: TObject);
  51. var
  52.   Index: Integer;
  53. begin
  54. {$IfDef Linux}
  55.   Exit;
  56. {$EndIf}
  57.   Index := CheckListBox1.ItemIndex;
  58.   CheckListBox1.Checked[Index] := not CheckListBox1.Checked[Index];
  59. end;
  60.  
  61. end.

 

TinyPortal © 2005-2018