7

我有下面的代码。如何根据是否选中项目来设置checkedListBox项目的前景色?

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

5 回答 5

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每个项目的设置(例如在 Collection 中)并引用CheckedColorusing Index. 但是,我认为这需要做很多工作。因此,如果您有这样的要求,ListView则改为选择会更好。

于 2013-07-11T08:44:54.500 回答
5

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

listView1.Items[i].ForeColor = Color.Red;
于 2013-07-11T08:43:07.667 回答
5

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

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);
    }
}
于 2016-12-01T11:02:19.473 回答
1

扩展@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());
于 2018-09-04T14:01:41.907 回答
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)))

这导致启用/禁用对我有用。

于 2018-11-02T10:46:14.110 回答