Can I use a DrawItem event handler with a CheckedListBox?

允我心安 提交于 2019-11-28 11:33:06

问题


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?


回答1:


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.




回答2:


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);


来源:https://stackoverflow.com/questions/18725111/can-i-use-a-drawitem-event-handler-with-a-checkedlistbox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!