Как изменить цвет SelectedItem в CheckedListBox в WindowsForms?

Я хочу изменить цвет элементов, отмеченных в CheckedListBox в С# WindowsForms.

Может ли кто-нибудь помочь мне решить эту проблему!


person kapil    schedule 25.01.2010    source источник


Ответы (2)


Это должно помочь вам начать. Я создал подкласс CheckedListBox и переопределил событие рисования. В результате все отмеченные элементы в списке отображаются на красном фоне.

Из игры с этим, если вы хотите, чтобы область за флажком также была другого цвета, используйте e.Graphics.FillRectangle перед вызовом 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);
    }
}
person Jon Seigel    schedule 06.11.2010

Спасибо, Джон, что навел меня на правильный путь, так как у меня было то же желание: чтобы цвет текста элемента был разным для каждого из 3 состояний флажка.

Я придумал этот подкласс CheckedListBox. Он изменяет текст элементов, а не цвет фона. Это позволяет пользователю устанавливать 3 цвета во время разработки или, конечно, в коде.

Это также устраняет проблему, из-за которой у меня возникала ошибка при просмотре элемента управления в конструкторе. Мне также пришлось преодолеть проблему, которая, как я думаю, возникла бы в вашем решении, когда при выборе элемента метод base.OnDrawItem стирает варианты выбора цвета, установленные в переопределенном методе OnDrawItem. Я сделал это за счет того, что выбранный элемент больше не имеет цветного фона, удалив часть e.State, в которой говорится, что он выбран, чтобы в base.OnDrawItem он не выглядел как выбранный элемент. Это нормально, хотя я думаю, поскольку пользователь все еще увидит прямоугольник фокуса, который указывает, что выбрано.

Надеюсь, это может быть полезно для других. Я не нашел много связного решения (даже просто полного метода OnDrawItem) при поиске в сети.

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); 
        }
      }
    }
  }
person Kent Kruckeberg    schedule 24.02.2011