2009-08-22 12 views
7

Używam OwnerDrawFixed jako DrawMode dla niestandardowego kontrolki ListBox w mojej aplikacji WinForm.ListBox DrawItem HotLight State w trybie OwnerDraw?

Chcę przemalować tle (czy jakieś inne działania) z ListBoxItem, gdy użytkownik nakieruje na element listbox, czyli na mouseMove ...

DrawItemState.HotLight nie pracuje dla ListBox, tak Zastanawiam się, jak naśladować to, jak obejść ten problem.

Odpowiedz

11

Zajęło mi dwa lata, aby znaleźć odpowiedź dla ciebie, ale tutaj jest:

DrawItemState.HotLight odnosi się tylko do właściciela rysowane menu, nie listbox. W przypadku ListBox musisz samodzielnie śledzić ten element:

public partial class Form1 : Form 
{ 
    private int _MouseIndex = -1; 

    public Form1() 
    { InitializeComponent(); } 

    private void listBox1_DrawItem(object sender, DrawItemEventArgs e) 
    { 
    Brush textBrush = SystemBrushes.WindowText; 

    if (e.Index > -1) 
    { 
     if (e.Index == _MouseIndex) 
     { 
     e.Graphics.FillRectangle(SystemBrushes.HotTrack, e.Bounds); 
     textBrush = SystemBrushes.HighlightText; 
     } 
     else 
     { 
     if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) 
     { 
      e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds); 
      textBrush = SystemBrushes.HighlightText; 
     } 
     else 
      e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds); 
     } 
     e.Graphics.DrawString(listBox1.Items[e.Index].ToString(), e.Font, textBrush, e.Bounds.Left + 2, e.Bounds.Top); 
    } 
    } 

    private void listBox1_MouseMove(object sender, MouseEventArgs e) 
    { 
    int index = listBox1.IndexFromPoint(e.Location); 
    if (index != _MouseIndex) 
    { 
     _MouseIndex = index; 
     listBox1.Invalidate(); 
    } 
    } 

    private void listBox1_MouseLeave(object sender, EventArgs e) 
    { 
    if (_MouseIndex > -1) 
    { 
     _MouseIndex = -1; 
     listBox1.Invalidate(); 
    } 
    } 
} 
+2

Cóż, 2 lata później ty też mi pomogłeś! ;) Ładny, prosty sposób na "hot tracking" w skrzynce na listy ... dzięki! – ChandlerPelhams

+1

A LarsTech pomoże wielu przez wiele lat ... Szukałem podobnej odpowiedzi i znalazłem ją tutaj. Dzięki. – ThN

+0

Jak to zrobić dla combobox? Combobox nie ma IndexFromPoint. –

0

To rozwiązanie po prostu waży twój kod; po prostu spróbuj tego:

If e.State And DrawItemState.Selected Then 
        e.Graphics.FillRectangle(SystemBrushes.HotTrack, e.Bounds) 
        e.Graphics.DrawString(drv, Me.Font, SystemBrushes.HighlightText, e.Bounds.X + 18, e.Bounds.Y + 1) 
       Else 
        e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds) 
        e.Graphics.DrawString(drv, Me.Font, SystemBrushes.ControlText, e.Bounds.X + 18, e.Bounds.Y + 1) 
End If 

Ta operacja: e.State And DrawItemState.Selected weryfikuje element jest unosił. Nie ma potrzeby umieszczania całej paczki kodu, aby wiedzieć, który przedmiot jest zawinięty.

+0

Twoje rozwiązanie nie rozwiązuje problemu, o który pytał OP. – LarsTech