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
Post a Comment