2013-09-10 7 views
1

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

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

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

+0

Вы можете быть заинтересованы в [лучшем решении] (http://stackoverflow.com/q/15532639/643085) к этой проблеме (и любым другим проблемам UI-конкретнее вы можете думать) –

ответ

3

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

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

+0

+1 для ваших усилий и придумать не очень простой код. Но я не думаю, что вы (= OP) должны даже рассмотреть возможность полагаться на рисование событий, если то, что он хочет, влияет на текст. Утверждение «Я не хочу, чтобы изменения, возвращаемые методом ToString(),« не явились причиной для меня (почему бы не переопределить метод ToString()?). Я не говорю все это только для этого конкретного случая, но в целом: лучше использовать рисование/рисование событий для рисования/рисования (= цвета, контуры и т. Д.) И текстовые для записи. Было бы проще и, скорее всего, гораздо надежнее. – varocarbas

+0

@varocarbas Я не согласен. Но с учетом ограничений OP, это единственный доступный курс. – DonBoitnott

0

Я продолжал работу в ответ DonBoitnotts.

«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); 
+0

Важно: чтобы избежать странных эффектов в тексте (визуальный, как жирный), код должен начинаться с e.DrawBackgroud(); – Taber

Смежные вопросы