2010-06-10 14 views
5

Estoy creando una aplicación de tablero que muestra cientos de "elementos" en un FlowLayoutPanel.Cientos de UserControls personalizados crean miles de objetos de usuario

Cada "artículo" es un UserControl que se compone de 12 cuadros de texto o etiquetas.

Mi aplicación consulta una base de datos y luego crea una instancia de "elemento" para cada registro, completando las etiquetas y cuadros de texto con datos antes de agregarlo al FlowLayoutPanel.

Después de agregar unos 560 elementos al panel, noté que el conteo USER Objects en mi Administrador de tareas había subido a aproximadamente 7300, que era mucho más grande que cualquier otra aplicación en mi máquina.

que pensé que 560 * 13 (12 etiquetas más el propio control de usuario) es 7280. Así que de repente se dio de distancia, donde todos los objetos venían de ...

Sabiendo que hay un límite de 10.000 objetos de usuario antes de Windows arroja la toalla, estoy tratando de encontrar mejores formas de dibujar estos "artículos" en el FlowLayoutPanel.

Mis ideas hasta el momento son los siguientes:

  1. usuario dibujar el "elemento", usando graphics.DrawText y DrawImage en lugar de muchas de las etiquetas. Estoy esperando que esto significará 1 punto = 1 USER Object, no 13.

  2. tienen 1 instancia del "elemento", a continuación, para cada registro, rellenar la instancia y utilizar el método Control.DrawToBitmap() para agarrar una imagen y luego el uso que en el FlowLayoutPanel (o similar)

Así que ... ¿alguien tiene alguna sugerencia ???

P.S. Es una interfaz con zoom, por lo que ya he descartado la "búsqueda" ya que existe un requisito para ver todos los elementos a la vez

Respuesta

2

Como mínimo, comenzaría con su idea n. ° 1. De hecho, esto reducirá el número de ventanas que su aplicación engulle por un factor de 13.

Respecto a su idea n. ° 2, eso no lo ayudará si coloca el mapa de bits en una PictureBox (o lo que sea) y tenga una gran cantidad de controles PictureBox en su formulario (esto podría ser peor, ya que los Bitmaps a veces se componen de un recurso más limitado que la RAM general, que es un problema completamente diferente de consumir demasiadas ventanas). Esto solo sería una buena idea si tomara los mapas de bits resultantes y los copiara en un solo control más grande (y luego descartando los mapas de bits).

Si toma este último enfoque, entonces realmente no hay necesidad de utilizar el paso intermedio de renderizar a un control, obtener una copia de Bitmap del control y luego dibujar ese mapa de bits en un control final. Tendría más sentido tomar el código/lógica que usa para representar el control, y en cambio representarlo directamente al control final (multi-elemento).

+0

En lugar de crear cientos de mapas de bits o cuadros de imagen, creo que el enfoque sería dibujar cada control directamente a la imagen de un solo 'PictureBox', o tener un solo mapa de bits" sprite "y dibujar todos los controles a ese. Aunque si realmente son etiquetas * just *, supongo que es más fácil utilizar un 'TextRenderer' y eludir por completo los controles: es difícil decir exactamente qué se debe dibujar aquí. – Aaronaught

+0

Lo alejaría de 'TextRenderer', ya que es bastante lento (en relación con' Graphics.DrawString'), pero estoy de acuerdo en que su mejor enfoque es simplemente renderizar cada fila de la base de datos directamente en un solo control (y preferiblemente solo renderizar las filas visibles). – MusiGenesis

1

Su idea n. ° 2 es la que yo recomendaría. Esto es exactamente cómo la lista y los controles de cuadrícula destinados a mostrar miles de registros pueden realizar in-place editing. Comienza con un solo control y lo mueve a donde lo necesite.

Si se necesita mostrar varios casos, al mismo tiempo, entonces es un poco más difícil - como usted menciona, lo más probable es que tenga que utilizar DrawToBitmap y mostrar la "imagen fantasma" del control.

O bien, supongo que hay algo de desplazamiento aquí (nadie puede ver los objetos de 7280 UI a la vez, ¿verdad?), Así que lo otro que se puede hacer es crear dinámicamente solo las instancias que realmente van a ser en la pantalla al mismo tiempo. Tendría que calcular el área visible y compararla con la lista de controles que se mostrarán, y solo mostrar los marcadores de posición si la IU se aleja demasiado para distinguir los detalles. Me imagino que el desplazamiento/zoom se convertiría en una operación bastante intensiva de CPU si hicieras esto; mejor simplemente no crearlos en absoluto.

1

Implementé # 1 con buenos resultados.

13 veces menos objetos de usuario, y también se siente más rápido y más receptivo.

Gracias por las sugerencias - ¡Me sorprende que este no sea un problema más común!

Cuestiones relacionadas