delphi - Only One CheckBox Checked at a time -


[compiler: delphi xe2]

i have spent day yesterday trying sorts of ways accomplish specific task have ended in same result.

using trzcheckgroup , example see has been checked ect..

procedure tfrmmain.cboptionschange(sender: tobject; index: integer; newstate: tcheckboxstate); var   itmindex0, itmindex1: integer; begin   { initialize itemindex's }   itmindex0 := -1;   itmindex1 := -1;    { return position index of string's(0 , 1) }   itmindex0 := cboptions.items.indexof('one');   itmindex1 := cboptions.items.indexof('two');    { checkbox has been checked }    cboptions.itemchecked[itmindex0] := true;   cboptions.itemchecked[itmindex1] := false; end; 

note: ^this not final code example of how dealing checkboxes.

things -

if cboptions.itemchecked[itmindex0]   cboptions.itemchecked[itmindex1] := false else cboptions.itemchecked[itmindex1] := true; 

they work first time evaluates true understand why. else bit in action when un-check first checkbox, not desired result.

seems event stops working , on of attempts has fired twice reason.

the newstate param on cblistoptionschange, , can me in anyway?

any on appreciated.

thanks.

if cboptions.itemchecked[itmindex0]   cboptions.itemchecked[itmindex1] := false else if cboptions.itemchecked[itmindex1]   cboptions.itemchecked[itmindex0] := false; 

see if second checkbox checked check first 1 works required, after cannot check second checkbox no more.


ken white - snippet(working). replaced name of component default people confused else, helps default naming save future questions.

procedure tform1.rzcheckgroup1change(sender: tobject; index: integer; newstate: tcheckboxstate); var   i: integer; begin   // keep event being fired again while we're here.   // code isn't clear actual name of   // component or event, (the event named `cblistoptionschange`,   // code references `cboptions` - don't know   // correct, change if needed in next line ,   // 1 in `finally` block below. i'm using `cblistoptions`   // here.   rzcheckgroup1.onchange := nil;    try     // if we're getting notified of new item being checked...     if newstate = cbchecked     begin       // iterate through items, unchecking aren't       // @ index became checked.       // wouldn't use `for..in`, because ordering works better here       := 0 rzcheckgroup1.items.count - 1         if <> index           rzcheckgroup1.itemchecked[i] := false; // ryan - changed cblistoptions.items[i].checked := false;     end;      // ryan - uncomment these 2 lines if want 1 of them checked @ times, set checkbox trying uncheck checked.      //if not rzcheckgroup1.itemchecked[index]     //  rzcheckgroup1.itemchecked[index] := true;        // reconnect event     rzcheckgroup1.onchange := rzcheckgroup1change;   end; end; 

i'm not familiar trzcheckgroup, current code check item @ itmindex0 , uncheck other.

tcheckboxstate defined in delphi documentation as

tcheckboxstate = (   cbunchecked,   cbchecked,   cbgrayed ); 

so newstate appears tell newly set state of checkbox, , index tells checkbox changing. of time, cbgrayed isn't used, because indicates value has never been set; it's useful when you're reading boolean (or bit) column in database , it's null.

this event isn't meant alternate state of 2 checkboxes, appear; it's meant let react when single item (among group of items) changes it's state:

procedure tfrmmain.cblistoptionschange(sender: tobject; index: integer;    newstate: tcheckboxstate); begin   case newstate of     cbunchecked: // whatever when cboptions.items[index] unchecked     cbchecked:   // whatever when cboptions.items[index] checked     cbgrayed:    // ignored unless null in db column indicated   end; end; 

to reverse state of 2 checkboxes (changing 1 alternate state , other it's opposite), can use (uses 2 standard tcheckbox controls same event defined both of onclick events):

procedure tfrmmain.checkboxclick(sender: object); var   chkbox: tcheckbox;   boxtotoggle: tcheckbox; begin   // if you're sure event tcheckbox   changingbox := tcheckbox(sender);   // if there's chance it's used else   // if (sender tcheckbox)   // begin   //   changingbox := tcheckbox(sender);    //      // or   //   changingbox := sender tcheckbox     if changingbox = checkbox1     boxtotoggle := checkbox2   else     boxtotoggle := checkbox1;    // disable event both checkboxes, doesn't   // fire recursively   changingbox.onclick := nil;   boxtotoggle.onclick := nil;   try     boxtotoggle.checked := not changingbox.checked;       // reconnect event handlers     changingbox.onclick := checkboxclick;     boxtotoggle.onclick := checkboxclick;    end; 

however, if you're dealing list of items 1 should checked , others unchecked, should using tradiogroup instead. gives behavior automatically. using checkboxes against normal windows gui behavior, , confuse users.

with being said (and strong objections doing this!), , untested because don't have component you're using, can try (this against better judgement write!):

procedure tfrmmain.cblistoptionschange(sender: tobject; index: integer;    newstate: tcheckboxstate); var   i: integer; begin   // keep event being fired again while we're here.   // code isn't clear actual name of   // component or event, (the event named `cblistoptionschange`,   // code references `cboptions` - don't know   // correct, change if needed in next line ,   // 1 in `finally` block below. i'm using `cblistoptions`   // here.   cblistoptions.onchange := nil;    try     // if we're getting notified of new item being checked...     if newstate = cbchecked     begin       // iterate through items, unchecking aren't       // @ index became checked.       // wouldn't use `for..in`, because ordering works better here       := 0 cblistoptions.items.count - 1         if <> index           cblistoptions.items[i].checked := false;     end;               // reconnect event     cblistoptions.onchange := cblistoptionschange;   end; end; 

to make sure it's clear, think very bad idea, , if working me i'd not allow it. it's wrong opposed expected windows behavior when there's proper option available, imo.


Comments