2009-01-22 13 views
6

Estoy tratando de hacer un tipo de control ImageListBox que mostrará una gran cantidad de miniaturas, como la que utiliza Picasa.Rellenar un FlowLayoutPanel con una gran cantidad de controles y miniaturas de pintura bajo demanda

Este es mi diseño:

Tengo un FlowLayoutPanel que se rellena con una gran cantidad de objetos UserControl, por ejemplo, 4.000. A cada UserControl se le asigna un delegado para el evento Paint. Cuando se llama al evento Paint, comprueba un caché de memoria para la miniatura y, si la imagen no está en el caché, lo recupera del disco.

que tienen dos problemas que estoy tratando de resolver:

  1. Parece que WinForms se disparará un evento Paint incluso si el UserControl no está a la vista. De hecho, solo 10 controles están a la vista, el resto no (el FlowLayoutPanel.AutoScroll está configurado en true). Como resultado, intenta recuperar miniaturas de todas las imágenes y eso lleva mucho tiempo.

  2. Agregando los objetos UserControl al FlowLayoutPanel toma un tiempo algo largo, unos 2-3 segundos. Puedo vivir con ella, pero me pregunto si hay una mejor manera de hacerlo que:

    UserControl[] boxes = new UserControl[N]; 
    // populate array 
    panel.SuspendLayout(); 
    panel.Controls.AddRange(boxes); 
    panel.ResumeLayout(); 
    
+1

Tienen casi el mismo problema. Estoy trabajando con "contratos" que pueden tener x filas (x controles en el panel flexible) y también veo el largo tiempo para llenar el panel con todos los controles. 2-3 segundos para 200 elementos (ni siquiera 4000 como en su caso). Ill "fav" esta pregunta con seguridad. ;) – Stefan

+0

Im allso using suspendlayout/resumelayout y visible verdadero/falso al llenar objetos. – Stefan

Respuesta

3

no añadiría que muchos controles de usuario. Más bien, tendría una serie de estructuras de datos que almacena información sobre qué miniatura usar, posicionamiento, etc., y luego maneja la representación de cada miniatura requerida.

Por supuesto, solo renderizará lo que necesita, marcando los eventos de pintura en su control y representando las miniaturas que están a la vista y que requieren renderización.

+0

Eso se volverá demasiado complejo para lo que lo necesito. Agregar los controles no es realmente un problema. Alguna idea de cómo resolver (1)? –

+1

Hay un límite global en el número de identificadores de ventana que puede tener su aplicación. Cada control de usuario genera al menos un identificador (más si tiene otros controles dentro) y su aplicación fallará si supera la cantidad permitida de identificadores. – Nick

+0

Hay un límite de aproximadamente 10K identificadores que el sistema operativo permitirá, por lo que, como en mi caso, cuando tengo un navegador con iconos potencialmente 200K-300K en una aplicación de navegador, la paginación es la única opción. –

1

Aha! Encontré algo.

Cuando el UserControl no está a la vista y recibe un evento Paint, entonces e.ClipRectangle.IsEmpty es verdadero.

5

Para mejorar la velocidad de llenado del FlowLayoutPanel con sus controles de usuario, desactive la actualización del diseño mientras agrega los controles.

Inmediatamente antes de su ciclo, llame al SuspendLayout() y luego al final llame al ResumeLayout(). Asegúrese de utilizar un try-finally para garantizar que se ejecuta ResumeLayout() incluso si se produce una excepción.

Cuestiones relacionadas