Pregunta

Esta es una aplicación C # Desktop.La propiedad DrawStyle de mi ListBox se establece en OwnerDrawFixed.

El problema: anularé el sorteo para dibujar texto en diferentes fuentes, y funciona.Pero cuando empiezo a cambiar el tamaño del formulario en el tiempo de ejecución, el elemento seleccionado se dibuja correctamente, pero el resto de ellos no se rediba, lo que hace que el texto se vea corrupto por artículos no seleccionados.

Aquí está mi código:

private void listDevices_DrawItem(object sender, DrawItemEventArgs e)
{
    e.DrawBackground();

    string textDevice = ((ListBox)sender).Items[e.Index].ToString();

    e.Graphics.DrawString(textDevice,
        new Font("Ariel", 15, FontStyle.Bold), new SolidBrush(Color.Black), 
        e.Bounds, StringFormat.GenericDefault);


    // Figure out where to draw IP
    StringFormat copy = new StringFormat(
        StringFormatFlags.NoWrap |
        StringFormatFlags.MeasureTrailingSpaces
    );
    copy.SetMeasurableCharacterRanges(new CharacterRange[] {new CharacterRange(0, textDevice.Length)});

    Region[] regions = e.Graphics.MeasureCharacterRanges(
        textDevice, new Font("Ariel", 15, FontStyle.Bold), e.Bounds, copy);

    int width = (int)(regions[0].GetBounds(e.Graphics).Width);
    Rectangle rect = e.Bounds;
    rect.X += width;
    rect.Width -= width;

    // draw IP
    e.Graphics.DrawString(" 255.255.255.255",
        new Font("Courier New", 10), new SolidBrush(Color.DarkBlue),
        rect, copy);

    e.DrawFocusRectangle();
}

listDevices.Items.Add("Device001");
listDevices.Items.Add("Device002");

Además, el elemento que se dibuja correctamente (el seleccionado) está parpadeando en el tamaño del tamaño.No hay Biggie, pero si alguien sabe por qué ... TNX

¿Fue útil?

Solución

Ponga el siguiente código en el evento de cambio de tamaño:

private void listDevices_Resize(object sender, EventArgs e) {
    listDevices.Invalidate();
}

Esto debería hacer que todo sea redibrado.

Para detener el parpadeo, necesita doble tamponamiento.

Para hacer esto, haga una nueva clase, derivada de ListBox y coloque lo siguiente en el constructor:

this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

o simplemente pegue esto en un archivo de código:

using System.Windows.Forms;

namespace Whatever {
    public class DBListBox : ListBox {
        public DBListBox(): base() {
            this.DoubleBuffered = true;
            // OR
            // this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        }
    }
}

Reemplazar "lo que sea" con el espacio de nombres que usa su proyecto, o hágalo algo más útil.Después de compilar, debe poder agregar una DBLISTBOX en el diseñador de formulario.

Otros consejos

te repro el problema. Existen varios errores en el código, el nombre de la fuente es "Arial", no debe ajustar RECT.WIDTH, se olvida de llamar a disponer () en las fuentes, cepillos y regiones. Pero no explican el comportamiento. Hay algo mal con el área de recortes que evita que el texto se actualice correctamente. No veo dónde ocurre, el estado de objeto gráfico está bien.

Graphics.DRAWSTRING () es un método muy problemático, realmente debe evitarlo. Todos los controles de formularios de Windows, incluido Listbox, use Textrenderer.DrawText (). Eso resuelve el problema cuando lo uso. Sé que la medición es más difícil, podría resolverlo al mostrar la dirección IP en un desplazamiento fijo. También se ve mejor, se alinearán en una columna de esa manera.

Parpadea porque usas E.DRAWBACKGROUND (). Eso borra el texto existente, dibuja el texto de nuevo en él. No creo que el doble tampón vaya a arreglar eso, tendrías que dibujar todo el artículo para que no tengas que dibujar el fondo. Es complicado Si no puede obtener el tamaño exacto del texto con la fuente grande, una solución es para atraer primero a un mapa de bits.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top