I would like to override the text displayed when an item is added to a checked list box. Right now it is using obj.ToString(), but I want to append some text, without changing the objects ToString method. I have seen examples of handling the DrawItem event for ListBoxs, but when I try to implement them, my event handler is not called. I have noted that the Winforms designer does not seem to allow me to assign a handler for the DrawItem event. Being stubborn, I just added the code myself
listbox1.DrawMode = DrawMode.OwnerDrawVariable;
listbox1.DrawItem += listbox1_DrawItem;
Am I trying to do the impossible?
Not impossible, but incredibly difficult. What you suggest will not work, note the meta-data in class CheckedListBox
for method DrawItem
:
// Summary:
// Occurs when a visual aspect of an owner-drawn System.Windows.Forms.CheckedListBox
// changes. This event is not relevant to this class.
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public event DrawItemEventHandler DrawItem;
Therefore, your only option is to derive your own class from CheckedListBox
, and in my limited testing, this will be a long road. You can handle the drawing simply enough, as such:
public class CustomCheckedListBox : CheckedListBox
{
protected override void OnDrawItem(DrawItemEventArgs e)
{
String s = Items[e.Index].ToString();
s += "APPEND"; //do what you like to the text
CheckBoxState state = GetCheckBoxState(e.State); // <---problem
Size glyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, state);
CheckBoxRenderer.DrawCheckBox(
e.Graphics,
e.Bounds.Location,
new Rectangle(
new Point(e.Bounds.X + glyphSize.Width, e.Bounds.Y),
new Size(e.Bounds.Width - glyphSize.Width, e.Bounds.Height)),
s,
this.Font,
false,
state);
}
}
Note the method GetCheckBoxState()
. What you get in the DrawItemEventArgs
is a DrawItemState
, not the CheckBoxState
you need, so you have to translate, and that's where things started to go downhill for me.
Soldier on, if you like, this should get you started. But I think it'll be a messy, long road.
I continued the work in DonBoitnotts answer.
The "GetCheckBoxState" is implemented using a very limited set with only two states.
var state = GetItemChecked(e.Index) ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
Vertically aligned the checkbox and left aligned the text.
var b = e.Bounds;
int checkPad = (b.Height - glyphSize.Height) / 2;
CheckBoxRenderer.DrawCheckBox(g, new Point(b.X + checkPad, b.Y + checkPad),
new Rectangle(
new Point(b.X + b.Height, b.Y),
new Size(b.Width - b.Height, b.Height)),
text, this.Font, TextFormatFlags.Left, false, state);