如何动态更改/设置checkedListBox项前颜色

时间:2013-07-11 08:15:15

标签: c# winforms checkedlistbox

我的代码如下。如何根据是否选中了项目来设置checkListBox项目前颜色?

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
            }
        }
}

5 个答案:

答案 0 :(得分:5)

我认为你必须像这样绘制自己的CheckedListBox item

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();
        }
    }
}

如果您想为每个项目设置不同的CheckedColor,则必须为每个项目存储CheckedColor设置(例如在集合中),并使用{{CheckedColor引用Index 1}}。不过,我认为这是一项很多工作要做。因此,如果您有这样的要求,那么转而使用ListView会更好。

答案 1 :(得分:4)

我认为你应该尝试ListView而不是checkListBox。它具有必要的属性,可以根据需要进行定制。只需将Checkboxes属性设置为true,然后在您的代码中添加forecolor:

listView1.Items[i].ForeColor = Color.Red;

答案 2 :(得分:2)

由于自己绘制这个东西相当复杂,你实际上可以让原始控件自行绘制 - 只需调整颜色。这是我的建议:

public class CustomCheckedListBox : CheckedListBox
{
    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        Color foreColor;
        if (e.Index >= 0)
        {
            foreColor = GetItemChecked(e.Index) ? Color.Green : Color.Red;
        }
        else
        {
            foreColor = e.ForeColor;
        }

        // Copy the original event args, just tweaking the fore color.
        var tweakedEventArgs = new DrawItemEventArgs(
            e.Graphics,
            e.Font,
            e.Bounds,
            e.Index,
            e.State,
            foreColor,
            e.BackColor);

        // Call the original OnDrawItem, but supply the tweaked color.
        base.OnDrawItem(tweakedEventArgs);
    }
}

答案 3 :(得分:0)

扩展@Mattias的答案,我制作了这个自定义控件来满足我的需求。我需要它的颜色取决于Checked值以外的其他因素。

public class CheckedListBoxColorable : CheckedListBox
{
    /// <summary>
    /// Controls the forecolors of the objects in the Items collection.
    /// If the item is not represented, it will have the default forecolor.
    /// </summary>
    public Dictionary<object, Color> Colors { get; set; }

    public CheckedListBoxColorable()
    {
        this.DoubleBuffered = true; //prevent flicker, not sure if this is necessary.
    }

    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        //Default forecolor
        Color foreColor = e.ForeColor;

        //Item to be drawn
        object item = null;

        if (e.Index >= 0) //If index is -1, no customization is necessary
        {
            //Find the item to be drawn
            if (this.Items.Count > e.Index) item = this.Items[e.Index];

            //If the item was found and we have a color for it, get the custom forecolor
            if (item != null && this.Colors != null && this.Colors.ContainsKey(item))
            {
                foreColor = this.Colors[item];
            }
        }

        // Copy the original event args, just tweaking the forecolor.
        var tweakedEventArgs = new DrawItemEventArgs(
            e.Graphics,
            e.Font,
            e.Bounds,
            e.Index,
            e.State,
            foreColor,
            e.BackColor);

        // Call the original OnDrawItem, but supply the tweaked color.
        base.OnDrawItem(tweakedEventArgs);
    }
}

用法:

//Set the colors I want for my objects
foreach (var obj in objects)
{
    //Add your own logic here to set the color depending on whatever criteria you have
    if (obj.SomeProperty) lstBoxes.Colors.Add(obj, Color.Green);
    else lstBoxes.Colors.Add(obj, Color.Red);
}
//Add the items to the checkedlistbox
lstBoxes.Items.AddRange(objects.ToArray());

答案 4 :(得分:0)

接受的答案对我有用,但是如果要禁用CustomCheckedListBox,则需要修改。

我将代码修改如下:-

我将“ CheckBoxRenderer.DrawCheckBox ...”行更改为

if(Enabled)
{
    CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(dx, e.Bounds.Top + dx), isChecked ? System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal : System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);
}
else
{
    CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(dx, e.Bounds.Top + dx), isChecked ? System.Windows.Forms.VisualStyles.CheckBoxState.CheckedDisabled : System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedDisabled);
}

然后我将'using(Brush brush = new SolidBrush ...'行更改为

using (Brush brush = new SolidBrush(isChecked ? CheckedItemColor : (Enabled ? ForeColor : SystemColors.GrayText)))

这导致启用/禁用为我工作。