2010-01-25 5 views

Répondre

7

Cela devrait vous aider à démarrer. J'ai sous-classé un CheckedListBox et remplacé l'événement de dessin. Le résultat est que tous les éléments cochés dans la liste sont dessinés avec un arrière-plan rouge.

Si vous souhaitez que la zone située derrière la case à cocher soit également de couleur différente, utilisez e.Graphics.FillRectangle avant d'appeler le 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); 
    } 
} 
4

Merci Jon qui m'a sur le droit chemin que j'ai eu le même désir: avoir la couleur du texte de l'élément différent pour chacun des 3 états de la case à cocher.

J'ai trouvé cette sous-classe de CheckedListBox. Il change le texte des éléments, pas la couleur d'arrière-plan. Il permet aux 3 couleurs d'être définies par l'utilisateur lors de la conception ou bien dans le code bien sûr.

Il résout également un problème que j'ai eu où j'ai eu une erreur lors de l'affichage du contrôle dans le concepteur. J'ai également dû surmonter un problème qui se serait produit dans votre solution. Si l'élément est sélectionné, la méthode base.OnDrawItem annule les choix de couleurs définis dans la méthode OnDrawItem substituée. Je l'ai fait au détriment de l'élément sélectionné ne plus avoir un arrière-plan coloré en supprimant la partie de e.State qui dit qu'il est sélectionné de sorte que dans la base.OnDrawItem il n'est pas fait pour être un objet sélectionné et l'impression. C'est ok mais je pense que l'utilisateur verra toujours le rectangle de focus qui indique ce qui est sélectionné.

Espérons que cela puisse être utile aux autres. Je n'ai pas trouvé grand-chose pour une solution cohérente (même juste une méthode OnDrawItem complète) quand on regarde sur le 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); 
     } 
     } 
    } 
    }