How change the color of SelectedItem in CheckedListBox in WindowsForms?

后端 未结 2 1169
暗喜
暗喜 2021-01-18 16:28

I want to change the color of the items that are chedked in the CheckedListBox in C# WindowsForms.

Can any one help me to solve this problem!

相关标签:
2条回答
  • 2021-01-18 16:34

    Thanks Jon that got me on the right path as I had the same desire: to have the item's text color be different for each of the 3 states of the checkbox.

    I came up with this subclass of the CheckedListBox. It changes the items text, not the background color. It lets the 3 colors be set by the user at design time or in code of course.

    It also fixes a problem I had where I got an error when viewing the control in the designer. I also had to overcome a problem I think would have happened in your solution where if the item is selected the base.OnDrawItem method obliterates the color choices set in the overridden OnDrawItem method. I did this at the expense of the selected item no longer having a colored background by removing the part of e.State that says it is selected so that in the base.OnDrawItem it is not made to be a selected item look and feel. This is ok though I think since the user will see the focus rectangle still which indicates which is selected.

    Hopefully this may be useful to others. I didn't find much for a cohesive solution (even just a complete OnDrawItem method) when looking on the net.

    using System;
    using System.Windows.Forms;
    using System.Drawing;
    
    namespace MyNameSpace
      {
      /// <summary>
      /// This is a CheckedListBox that allows the item's text color to be different for each of the 3 states of the corresponding checkbox's value.
      /// Like the base CheckedListBox control, you must handle setting of the indeterminate checkbox state yourself.
      /// Note also that this control doesn't allow highlighting of the selected item since that obscures the item's special text color which has the special meaning.  But 
      /// the selected item is still known to the user by the focus rectangle it will have surrounding it, like usual.
      /// </summary>
      class ColorCodedCheckedListBox : CheckedListBox
        {
        public Color UncheckedColor { get; set; }
        public Color CheckedColor { get; set; }
        public Color IndeterminateColor { get; set; }
    
        /// <summary>
        /// Parameterless Constructor
        /// </summary>
        public ColorCodedCheckedListBox() 
          {
          UncheckedColor = Color.Green;
          CheckedColor = Color.Red;
          IndeterminateColor = Color.Orange;
          }
    
        /// <summary>
        /// Constructor that allows setting of item colors when checkbox has one of 3 states.
        /// </summary>
        /// <param name="uncheckedColor">The text color of the items that are unchecked.</param>
        /// <param name="checkedColor">The text color of the items that are checked.</param>
        /// <param name="indeterminateColor">The text color of the items that are indeterminate.</param>
        public ColorCodedCheckedListBox(Color uncheckedColor, Color checkedColor, Color indeterminateColor) 
          {
          UncheckedColor = uncheckedColor;
          CheckedColor = checkedColor;
          IndeterminateColor = indeterminateColor;
          }
    
        /// <summary>
        /// Overriden draw method that doesn't allow highlighting of the selected item since that obscures the item's text color which has desired meaning.  But the 
        /// selected item is still known to the user by the focus rectangle being displayed.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnDrawItem(DrawItemEventArgs e)
          {
          if (this.DesignMode)
            {
            base.OnDrawItem(e); 
            }
          else
            {
            Color textColor = this.GetItemCheckState(e.Index) == CheckState.Unchecked ? UncheckedColor : (this.GetItemCheckState(e.Index) == CheckState.Checked ? CheckedColor : IndeterminateColor);
    
            DrawItemEventArgs e2 = new DrawItemEventArgs
               (e.Graphics,
                e.Font,
                new Rectangle(e.Bounds.Location, e.Bounds.Size),
                e.Index,
                (e.State & DrawItemState.Focus) == DrawItemState.Focus ? DrawItemState.Focus : DrawItemState.None, /* Remove 'selected' state so that the base.OnDrawItem doesn't obliterate the work we are doing here. */
                textColor,
                this.BackColor);
    
            base.OnDrawItem(e2); 
            }
          }
        }
      }
    
    0 讨论(0)
  • 2021-01-18 16:52

    This should get you started. I've subclassed a CheckedListBox and overridden the drawing event. The result is all checked items in the list are drawn with a red background.

    From playing around with this, if you want the area behind the checkbox to be a different colour as well, use e.Graphics.FillRectangle before calling base.OnDrawItem.

    class ColouredCheckedListBox : CheckedListBox
    {
        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            DrawItemEventArgs e2 =
                new DrawItemEventArgs
                (
                    e.Graphics,
                    e.Font,
                    new Rectangle(e.Bounds.Location, e.Bounds.Size),
                    e.Index,
                    e.State,
                    e.ForeColor,
                    this.CheckedIndices.Contains(e.Index) ? Color.Red : SystemColors.Window
                );
    
            base.OnDrawItem(e2);
        }
    }
    
    0 讨论(0)
提交回复
热议问题