2012-03-18 9 views
10

Tengo una aplicación SL con muchos DataGrids (desde Silverlight Toolkit), cada uno en su propia vista. Si se abren varios DataGrids, el cambio entre vistas (TabItems, por ejemplo) lleva mucho tiempo (unos segundos) y congela toda la aplicación (subproceso de interfaz de usuario).Rendimiento de Silverlight con muchos controles cargados

Cuantos más DataGrids se carguen, más tardará el cambio. Estos DataGrids que ralentizan el heap de UI pueden estar en otros lugares de la aplicación y no ser visibles en ese momento. Pero una vez que se abren (y se cargan con datos), se ralentizan mostrando otros DataGrids. Tenga en cuenta que los DataGrids NO se eliminan y luego se vuelven a crear, aún permanecen en la memoria, solo su control principal se oculta y se vuelve a ver.

He creado un perfil para la aplicación. Muestra que la función SetValue de agcore.dll es el cuello de botella. Lamentablemente, los símbolos de depuración no están disponibles para esta biblioteca nativa de Silverlight responsable del dibujo.

El problema no está en el control DataGrid: intenté reemplazarlo con la cuadrícula de XCeed y el rendimiento al cambiar las vistas es aún peor.

¿Tiene alguna idea de cómo resolver este problema? ¿Por qué más controles abiertos ralentizan otros controles?

He creado un ejemplo que muestra este problema: VS solution, live demo

ACTUALIZACIÓN: El uso de perfiles VS11 de la muestra prevista sugiere que el problema podría estar en MeasureOverride ser llamado muchas veces (para cada DataGridCell, me adivinar). Pero aún así, ¿por qué es más lento a medida que se cargan más controles en otros lugares? ¿Hay alguna forma de mejorar el rendimiento?

ACTUALIZACIÓN 2: Debo mencionar que no uso TabControl en mi aplicación particular. Uso Caliburn.Micro y ContentControl para mostrar ViewModel actualmente activo. Pero el mismo problema es con TabControl, así que lo usé para describir el problema central.

+2

Véase la discusión aquí (lo de TabControl), se puede ayudar: http://stackoverflow.com/questions/1389769/wpf-virtualizingstackpanel-for-increased-performance – Phil

+0

En realidad, en mi aplicación original, uso Caliburn.Micro (framework MVVM) así que en lugar de un TabControl, tengo un ContentControl vinculado a ViewModel actualmente activo (y por lo tanto su vista). Sin embargo, verificaré la discusión y te haré saber. ¡Gracias! – gius

+0

filedropper 404'ed –

Respuesta

5

Entonces, seguí la idea de crear controles personalizados y aquí está el resultado: http://www.baud.cz/blog/fast-switching-between-viewmodels-in-caliburn.micro.

Enlaces rápidos a aplicaciones de demostración MVVM: Original y Fixed

+0

+1. Esto es lo que terminamos haciendo en un proyecto. Tuvimos la misma configuración 'TabControl' con pérdida visual y también utilizamos Caliburn. Y la solución fue almacenar en caché y devolver vistas en caché con 'IViewAware.GetView' – nemesv

+1

AFAIK, IViewAware.GetView en Caliburn.Micro ya almacena en caché las vistas. Creo que uno puede ver cambiando las vistas en TabControl donde la posición de la barra de desplazamiento persiste (esto no se guarda en la máquina virtual). – gius

0

Experimentamos algo similar a esto, estábamos cargando dinámicamente muchos controles de usuario cargados de control y cuanto más se renderizaban, más lenta parecía la aplicación. Por loco que suene, cuando establecimos la raíz de diseño de cada control en un control de borde, los problemas de rendimiento disminuyeron significativamente ya que el sistema de diseño no tuvo que luchar tanto para actualizar todos los recursos.

Solo quería compartir algo que funcionó un milagro para nosotros que usted podría intentar.

0

Esta es una suposición casi salvaje, pero me pregunto si esto ayudaría a establecer Visibilidad en Colapsado en pestañas que no están seleccionadas. (Supongo fila virtualización está habilitado en la cuadrícula de datos. Eso me ha ayudado mucho en el pasado.)

Mi conjetura semi-salvaje se basa principalmente en este tip y en mi comprensión intermedia de la información que se encuentra here.

+1

De hecho, reescribí la muestra provista al usar MVVM y mostré el contenido activo en un ContentControl que usaba un convertidor para representar las vistas con solo un activo y aún así fue lento. – Bryant

+0

@Bryant ese es exactamente mi problema. Acabo de usar TabControl para simplificarlo lo más posible. La posible solución que puedo ver es crear un ContentContr personalizado viejo (probablemente basado en ItemsControl) que además del elemento activo de alguna manera mantiene las otras vistas para que no se eliminen del árbol visual y, por lo tanto, no es necesario volver a crearlas cuando se activa la vista respectiva. – gius

0

tuve este problema con c1DataGrid, he encontrado que después de girar temas fuera, pestañas cambiantes fue rápido, y hacer otras operaciones de la interfaz de usuario estaban confirmación.

Proveedores:

  1. asegurar que ninguno de su código está siendo llamado por pisar a través de VS.
  2. Retire todos los estilos aplicados
  3. si todavía eliminar lenta componente a componente, tal vez no es sólo la cuadrícula de datos
  4. reemplazar su cuadrícula de datos con c1datagrid
Cuestiones relacionadas