System.Windows.Forms.CheckedListBox: Best way to enable only the not Indeterminate ones.

2 views
Skip to first unread message

per9000

unread,
Feb 3, 2009, 10:23:06 AM2/3/09
to
Hejsan!

I want to make a System.Windows.Forms.CheckedListBox where only some
of the values are clickable.

I googled a bit and the best way I seemed to find was to disable
clicking, setting the SelectionMode to None and making a custom event
handler upon click.

<code>
this.checkedListBox1.SelectionMode =
System.Windows.Forms.SelectionMode.None;
this.checkedListBox1.Click += new System.EventHandler
(this.checkedListBox1_Click1);
</code>

My event handler does a raw computation of the index clicked and
toggles it if it was Unchecked or Checked.

<code>
void checkedListBox1_Click1(object sender, System.EventArgs e)
{
MouseEventArgs mev = e as MouseEventArgs;
if (mev == null)
return;

int n = (mev.Y / checkedListBox1.ItemHeight);

if (n >= checkedListBox1.Items.Count)
return;

CheckState state = checkedListBox1.GetItemCheckState(n);

if (state == CheckState.Unchecked || state ==
CheckState.Checked) // TODO: optimize this row
checkedListBox1.SetItemChecked(n, state ==
CheckState.Unchecked);
}
</code>

My question is more or less: is there a better way of doing this? This
method is hopelessly flawed: I can not toggle items with the keyboard
for example.

See blog entry with fancy screen shot here:
http://www.pererikstrandberg.se/blog/index.cgi?page=CsharpCheckedListBoxTest,
complere sample code here http://www.pererikstrandberg.se/blog/code/clbTestForm.cs
and executable here http://www.pererikstrandberg.se/blog/code/clbTestForm.exe

Thanks
Per

Ben Voigt [C++ MVP]

unread,
Feb 3, 2009, 11:45:28 AM2/3/09
to

"per9000" <per...@gmail.com> wrote in message
news:d0fd5c37-7bd1-41cf...@z6g2000pre.googlegroups.com...


> Hejsan!
>
> I want to make a System.Windows.Forms.CheckedListBox where only some
> of the values are clickable.
>
> I googled a bit and the best way I seemed to find was to disable
> clicking, setting the SelectionMode to None and making a custom event
> handler upon click.

Why not handle ItemCheck and set the NewValue property back to CurrentValue
for items which are supposed to be read-only?

Here is the description of the NewValue property:
<quote>
Remarks

This property enables you to determine the new check state for the specified
item before the check state is changed by the CheckedListBox control. In
addition to determining the new check state, you can use this property in an
event handler for the ItemCheck event to change the state to a different
check state than the one specified. For example, if the user placed a check
mark next to an item in the CheckedListBox that you have determined should
not be checked based on the state of your application, you can override the
change in the check mark state by setting this property to its previous
setting or to a different check state.
</quote>

http://msdn.microsoft.com/en-us/library/system.windows.forms.itemcheckeventargs.newvalue.aspx

per9000

unread,
Feb 4, 2009, 2:38:07 AM2/4/09
to
On 3 Feb, 17:45, "Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote:
> "per9000" <per9...@gmail.com> wrote in message
>
> <snip />

>
> > I want to make a System.Windows.Forms.CheckedListBox where only some
> > of the values are clickable.
>
> <snip />

>
> Why not handle ItemCheck and set the NewValue property back to CurrentValue
> for items which are supposed to be read-only?
>
> Here is the description of the NewValue property:
> <quote>
> Remarks
>
> <snip /> change the state to a different

> check state than the one specified. For example, if the user placed a check
> mark next to an item in the CheckedListBox that you have determined should
> not be checked based <snip />
> </quote>
>
> <snip />


Thanks! Purrr-fect!

<code>
this.checkedListBox1.CheckOnClick = true;
this.checkedListBox1.ItemCheck += new
System.Windows.Forms.ItemCheckEventHandler
(this.checkedListBox1_ItemCheck);

void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (e.CurrentValue == CheckState.Indeterminate)
e.NewValue = e.CurrentValue;
}
</code>


/Per

Reply all
Reply to author
Forward
0 new messages