StackTrace StackTrace - 5 days ago 5
C# Question

How to dynamically change / set checkedListBox item fore colour

I have code below. How can i set checkedListBox item fore colour depending on if item is checked or not checked?

private void FindSelectedUserRoles()
{
lblSelectedUser.Text = Code.CommonUtilities.getDgvStringColValue(dataGridViewUserList, "UserName").Trim();

//iterate all roles selected user is member of
for (int i = 0; i < checkedListRoles.Items.Count; i++)
{
string roleName = checkedListRoles.Items[i].ToString();
string selectedUserRoles = Code.MemberShipManager.GetSpecificUsersRoles(lblSelectedUser.Text.Trim());

if (selectedUserRoles.Contains(roleName))
{
checkedListRoles.SetItemChecked(i, true);
//here i want to set item fore colour to green

}
else if (selectedUserRoles.Contains(roleName) == false)
{
checkedListRoles.SetItemChecked(i, false);
//and here, i want item fore colour to remain black
}
}
}

Answer

I think you have to draw your own CheckedListBox item like this:

public class CustomCheckedListBox : CheckedListBox
{
    public CustomCheckedListBox()
    {
        DoubleBuffered = true;
    }
    protected override void OnDrawItem(DrawItemEventArgs e)
    {            
        Size checkSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, System.Windows.Forms.VisualStyles.CheckBoxState.MixedNormal);
        int dx = (e.Bounds.Height - checkSize.Width)/2;
        e.DrawBackground();
        bool isChecked = GetItemChecked(e.Index);//For some reason e.State doesn't work so we have to do this instead.
        CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(dx, e.Bounds.Top + dx), isChecked ? System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal : System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);
        using (StringFormat sf = new StringFormat { LineAlignment = StringAlignment.Center })
        {
            using (Brush brush = new SolidBrush(isChecked ? CheckedItemColor : ForeColor))
            {
                e.Graphics.DrawString(Items[e.Index].ToString(), Font, brush, new Rectangle(e.Bounds.Height, e.Bounds.Top, e.Bounds.Width - e.Bounds.Height, e.Bounds.Height), sf);
            }
        }            
    }
    Color checkedItemColor = Color.Green;
    public Color CheckedItemColor
    {
        get { return checkedItemColor; }
        set
        {
            checkedItemColor = value;
            Invalidate();
        }
    }
}

If you want to set CheckedColor differently for each item, you have to store the CheckedColor setting for each item (such as in a Collection) and reference the CheckedColor using Index. However I think it's a little much work to do. So if you have such a requirement, going for ListView instead would be better.