Pregunta

Necesito dibujar cada elemento en un cuadro de lista basado en el texto de los elementos que están a punto de agregarse o el texto que contiene. Luego necesito colocar un icono al comienzo del cuadro de lista, con otros dos colores e iconos dependiendo de las palabras que especifique, por ejemplo,

  • Si el elemento contiene texto de error, coloque un icono de error (16x16px) al principio y dibuje el fondo en rojo claro y el texto en negrita rojo oscuro.

  • Si contiene un texto listo o inicial, use fondo naranja claro y texto de fuente azul oscuro y audaz.

  • Si contiene un texto de OK o éxito, use fondo verde claro y texto de fuentes verdes oscuro y audaz.

¿Cómo puedo hacer esto?

EDITAR

Esto es lo que ya tengo, pero este código parece refrescar sin fin. Donde necesito elegir el color es el valor de E.Index. ¿Puedo cambiar el e.index a somthinf como E.StringValue?

Private Sub lsbLog_DrawItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles lsbLog.DrawItem
        '//Draw the background of the ListBox control for each item.
        '// Create a new Brush and initialize to a Black colored brush
        '// by default.
        e.DrawBackground()
        Dim mybrush = Brushes.Black

        '// Determine the color of the brush to draw each item based on 
        '//the index of the item to draw.
        Select Case e.Index
            Case 0
                mybrush = Brushes.Red
            Case 1
                mybrush = Brushes.Blue
            Case 2
                mybrush = Brushes.Green
        End Select

        '//
        '// Draw the current item text based on the current 
        '// Font and the custom brush settings.
        '//
        e.Graphics.DrawString(lsbLog.Items(e.Index).ToString(), _
                              e.Font, mybrush, e.Bounds, StringFormat.GenericDefault)
        '//
        '// If the ListBox has focus, draw a focus rectangle 
        '// around the selected item.
        '//
        e.DrawFocusRectangle()
        lsbLog.Refresh()
    End Sub
¿Fue útil?

Solución

En respuesta a sus dos preguntas específicas:

  1. El código que ha mostrado refresca sin cesar porque ha agregado una llamada a Refresh al final:

    lsbLog.Refresh()
    

    Saca eso y resolverás el problema de actualización interminable.

  2. Sí, ciertamente puede probar el subtítulo del elemento en lugar de su índice, pero no existe la propiedad como e.stringvalue. Tendrás que hacerlo de una manera diferente, una forma que ya has descubierto y usado en tu llamada a DrawString:

    lsbLog.Items(e.Index).ToString()
    

    Es posible que desee hacer algo un poco más complejo de lo que tengo, dependiendo de lo que generalmente contengan los elementos. Por ejemplo, es posible que desee verificar si la cadena contiene Las palabras clave, en lugar de probar la igualdad. Para obtener más flexibilidad, es posible que deba reemplazar Select Case con un If-Else declaración.


Entonces, algunas modificaciones menores más tarde, termino con el siguiente código:

Private Sub lsbLog_DrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs) Handles lsbLog.DrawItem
    '//Draw the background of the ListBox control for each item.
    '// Create a new Brush and initialize to a Black colored brush
    '// by default.
    e.DrawBackground()
    Dim mybrush As Brush = Brushes.Black

    '// Determine the color of the brush to draw each item based on 
    '//the index of the item to draw.
    Select Case lsbLog.Items(e.Index).ToString
        Case "Error"
            mybrush = Brushes.Red
        Case "Ready"
            mybrush = Brushes.Blue
        Case "Success"
            mybrush = Brushes.Green
    End Select

    '//
    '// Draw the current item text based on the current 
    '// Font and the custom brush settings.
    '//
    e.Graphics.DrawString(lsbLog.Items(e.Index).ToString(), _
                          e.Font, mybrush, e.Bounds, StringFormat.GenericDefault)
    '//
    '// If the ListBox has focus, draw a focus rectangle 
    '// around the selected item.
    '//
    e.DrawFocusRectangle()
End Sub

Y así es como se ve el resultado:

   ListBox with owner drawn items


Por supuesto, para cumplir completamente con sus requisitos, también deberá completar los antecedentes de cada artículo. La mejor manera de hacerlo es usar algo como lo siguiente, pero cambiar el color del pincel en consecuencia:

e.Graphics.FillRectangle(Brushes.Coral, e.Bounds)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top