Могу ли я использовать обработчик событий DrawItem с CheckedListBox?

Я хотел бы переопределить текст, отображаемый при добавлении элемента в отмеченный список. Прямо сейчас это использует obj.ToString(), но я хочу добавить некоторый текст, не изменяя метод ToString объектов. Я видел примеры обработки события DrawItem для ListBoxs, но когда я пытаюсь реализовать их, мой обработчик событий не вызывается. Я заметил, что дизайнер Winforms, похоже, не позволяет мне назначить обработчик для события DrawItem. Будучи упрямым, я просто добавил код сам

        listbox1.DrawMode = DrawMode.OwnerDrawVariable;
        listbox1.DrawItem += listbox1_DrawItem;

Я пытаюсь сделать невозможное?

2 ответа

Не невозможно, но невероятно сложно. То, что вы предлагаете, не будет работать, обратите внимание на метаданные в классе CheckedListBox для метода 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;

Таким образом, ваш единственный вариант - вывести собственный класс из CheckedListBoxи в моем ограниченном тестировании это будет долгий путь. Вы можете обработать рисунок достаточно просто, как таковой:

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

Обратите внимание на метод GetCheckBoxState(), Что вы получаете в DrawItemEventArgs это DrawItemState, не CheckBoxState вам нужно, так что вы должны переводить, и вот тут-то и начались проблемы со мной.

Солдат, если хотите, это должно помочь вам начать. Но я думаю, что это будет грязный, долгий путь.

Я продолжил работу в ответе ДонБойтнотса.

GetCheckBoxState реализован с использованием очень ограниченного набора только с двумя состояниями.

var state = GetItemChecked(e.Index) ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;

Выровняйте по вертикали флажок и выровняйте текст по левому краю.

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);
Другие вопросы по тегам