Can I use a DrawItem event handler with a CheckedL

2020-02-15 07:05发布

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?

2条回答
Summer. ? 凉城
2楼-- · 2020-02-15 07:25

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);
查看更多
3楼-- · 2020-02-15 07:38

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.

查看更多
登录 后发表回答