Forum > LCL

TCheckListBox with OnClick & OnClickCheck

(1/5) > >>

andyH:
I suspect this is expected behaviour, but it is unwanted...

Have a TCheckListBox, and in the constructor:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  Box3.OnClick:= @Box3CK;
And in Box3CK:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Source:= Box3.ItemIndex;CheckStatus:= Checked[Source];writeln('box3 clicked on item ',Source);//do some checks on the item, if it passesChecked[Source]:= not CheckStatus;
The problem is that:

* if I click on the item text in the checklistbox the event handler is run once = desired behaviour
* if I click on the item checkbox the event handler is run twice = undesired
Terminal output:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---box3 clicked on item 4  <<<< clicking once on item text = run oncebox3 clicked on item 3  <<<< clicking once on item checkbox = run twicebox3 clicked on item 3
I suspect this is because I'm changing the state of the checkbox in the event handler?

I get the same behaviour if I also set Box3.OnClickCheck:= @Box3CK as well, no surprise, but I thought I'd check.  It did crash cinnamon (windows users = my linux desktop environment), but it wasn't repeatable.

Most of the time this is not a problem, but if the item in the checklistbox fails a test an error message dialog is displayed. If the user has clicked on the checkbox, this message appears twice = undesired.

I could:

* set an event handler for OnClickCheck that does nothing, but this would mean the user has to click on the item text for anything to happen.

* the OnClick handler recording the item index clicked in a global var - OnClickCheck reads this and if no change does nothing. Downside - the user has to then click on another checkbox before they can change the state of the original checkbox.
* as above, but include time clicked, if OnClickCheck event handler called within say, 100ms, do nothing. But this is starting to get complicated...
Is there a better way, all I want is my event handler to run once whether the user clicks on the item text or checkbox?




winni:
Hi!

That's bad design because you created an endless loop by default.

But without changing the design you can get around the problem:

   
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- Source:= Box3.ItemIndex;    CheckStatus:= Checked[Source];    writeln('box3 clicked on item ',Source);    //do some checks on the item, if it passes    Box3.OnClick := Nil;    Checked[Source]:= not CheckStatus;    Box3.OnClick :=  @Box3CK; 
Winni

VTwin:
What widget set? I ran into a similar problem with TComboBox on Carbon, setting it in code was triggering the OnChange event.

It did not happen in Windows or Linux, so I assumed it was a Carbon bug. However, I was told it was expected behavior. My work around (an alternative to winni's, but not necessarily better) was to have a "fIsSetting" flag. The TComboBox checked this and exited if true.

Now Cocoa does not do this, so I assume it was a Carbon bug. Now Mac, Linux, and Windows all behave the same.

You might try this on several platforms, it sounds like a bug to me. I agree with jamie that this is at least undesirable behavior.

VTwin:
Perhaps I misunderstood. I tried to reproduce the bug with a simple example. This project works as expected on Windows, Linux, and Mac.

Can you post an example to illustrate the bug?

andyH:
GTK2 and the end application is linux (ubuntu) only.

Based on the comments I looked and realised I was also setting selection = false, which I think was the primary cause of the event handler firing twice. Most of my problems have gone away.

I tried winnie's suggestion:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Box3.OnClick:= Nil;Checked[Source]:= not CheckStatus;Box3.OnClick:= @Box3CK;Problem here is that first click on item text does nothing, subsequent clicks toggle state. Clicking on the checkbox does not toggle state (no event handler defined for OnClickCheck).

In this checklistbox, the first item is the partition table in a backup:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---       if Source = 0 then //it's the partition table - if changed it must be restored          begin            Checked[Source]:= true; //default assuming part table has changed            if CheckPartTable then Checked[Source]:= not CheckStatus;            //check to see if there is an extended partition, its state = state of part table            //for i:= 1 to Count - 1 do if pos(ExtendStr,Items[i]) > 0 then Checked[i]:= Checked[Source];            exit;          end; This is now behaving as it should - if the partition table has changed, the checkbox MUST be enabled. Although I have managed click on the item text occasionally and the handler not fire (but not in a repeatable fashion). Also managed to get to a point where I could toggle the checkbox with the Enter key - something I need to track down, doing a restore and not restoring a partition table that has changed would be a disaster.

Making progress, thanks to the comments received, but not quite there yet.
thanks  :)

Navigation

[0] Message Index

[#] Next page

Go to full version