Saltar al contenido
Optimizing Infragistics XamDataGrid Performance

Optimizing Infragistics XamDataGrid Performance

El componente XamDataGrid, uno de los controles del producto de línea de negocio NetAdvantage para WPF (versión de prueba gratuita disponible aquí) es el componente que se usa con más frecuencia de nuestro producto WPF. Presenta sus datos tabulares y le permite agrupar, ordenar, filtrar, calcular resúmenes de columnas, así como controlar su diseño mediante la agrupación de columnas, el reordenamiento, el anclaje y muchos más.

10min read

El componente XamDataGrid, uno de los controles del producto de línea de negocio NetAdvantage para WPF (versión de prueba gratuita disponible aquí) es el componente que se usa con más frecuencia de nuestro producto WPF. Presenta sus datos tabulares y le permite agrupar, ordenar, filtrar, calcular resúmenes de columnas, así como controlar su diseño mediante la agrupación de columnas, el reordenamiento, el anclaje y muchos más.

XamDataGrid también es capaz de manejar actualizaciones de datos en tiempo real y grandes volúmenes de datos de manera eficiente. En estos escenarios, el rendimiento de XamDataGrid es fundamental para la facilidad de uso de la aplicación. Es por eso que en esta publicación, veremos lo que puede hacer para maximizar su rendimiento.

Built-In Optimizations

XamDataGrid usa una variedad de métodos internos para asegurarse de que obtiene el mejor rendimiento: reutiliza los elementos del presentador tanto en el nivel de registro como en el de celda, almacena en caché la información de estilo, usa el desplazamiento diferido de la información sobre herramientas y la creación de objetos diferidos. Hay disponible información más específica sobre las optimizaciones de rendimiento. Sin embargo, todas estas optimizaciones ya se han integrado en el control y vienen listas para usar sin costo alguno.

Entonces, ¿cuáles son las formas en que puede mejorar el rendimiento? He elaborado una lista de puntos que podría considerar usar, la mayoría de los cuales se implementan en el proyecto de muestra. He intentado proporcionar la mayor cantidad de información posible sobre cómo estas estrategias afectan al aspecto o el comportamiento de la aplicación, para que pueda tener en cuenta los requisitos específicos del escenario y tomar una decisión informada sobre cuáles usar.

Enlace a valores preformateados

Una manera de mejorar el rendimiento en las columnas de solo lectura es reducir el formato de valor. A menudo, el formato de valores se implementa mediante convertidores, ya que es una forma fácil y limpia de encapsular la lógica de formato. Sin embargo, al desplazarse, la cuadrícula hace que la lógica del convertidor se invoque cada vez que se muestra una celda: al desplazarse horizontalmente para mostrar una nueva columna, el convertidor se invoca un número de veces igual al número de filas visibles. La sobrecarga de este procesamiento aumenta cuando se utilizan actualizaciones en tiempo real. Una manera de reducir la carga es realizar el formato de valor en el código y enlazar la cuadrícula al resultado formateado, que se calcula solo una vez. Además, con un enfoque diferido, un valor se puede formatear una vez y luego almacenarse en caché, lo que esencialmente elimina cualquier necesidad de que la interfaz de usuario active el formato.

Supongamos que tiene un objeto de negocio Product con un valor Price al que le gustaría dar formato de una manera específica. Una manera de hacerlo es ampliar el producto original mediante un FormattedProduct, que agrega una propiedad PriceFormatted, que se calcula cuando se solicita y se almacena para solicitudes posteriores. Si hay un número relativamente pequeño de valores únicos, una manera de reducir aún más el requisito de espacio de este enfoque de almacenamiento en caché es usar un diccionario para los valores con formato.

A continuación, una vez que se enlace a una lista de estos FormattedProducts, debe evitar que se muestre la columna Price y cambiar el encabezado de la columna PriceFormatted, que mostrará sus valores con formato. Puede hacerlo en el controlador de eventos del evento FieldLayoutInitialized, donde puede establecer la columna Visibility of the Price en Collapsed y la propiedad Label de PriceFormatted en 'Price'.

Estilismo

Estilos sin cursor

Se puede lograr un aumento sustancial del rendimiento estableciendo un estilo que se abstenga de aplicar colores y efectos en los elementos visuales más utilizados. Un ejemplo de ello es no establecer ningún color en la fila sobre la que se pasa el puntero. Descargue el estilo sin cursor de XamDataGrid de alto rendimiento. Por supuesto, es posible que desee seguir usando algunas de estas propiedades de estilo y puede modificarlas para adaptarlas a sus necesidades. Agregue este archivo al proyecto y haga referencia a él desde XamDataGrid de la siguiente manera:

<igDP:XamDataGrid.Resources>
   <ResourceDictionary Source="HoverlessStyles.xaml" />
</igDP:XamDataGrid.Resources>

Minimalist Styles

Al definir sus propias plantillas para elementos que aparecen muchas veces en la jerarquía visual, como CellValuePresenters, intente usar el menor número posible de elementos. Se inicializará una plantilla para todos los CellValuePresenters a la vista, lo que puede hacer que el número total de elementos visuales aumente rápidamente, lo que tiene un efecto adverso en el rendimiento. Hay disponible una explicación más detallada sobre el impacto de los estilos en el rendimiento. El CellValuePresenter mínimo consta de un Border que encierra un TextBlock. Un detalle importante necesario para mejorar el rendimiento cuando se usa el estilo minimalista es establecer la propiedad ForceCellVirtualization (nueva en 11.1) en true. Agregue este archivo de estilo minimalista al proyecto y haga referencia a él desde XamDataGrid de la siguiente manera:

<igDP:XamDataGrid.Resources>
   <ResourceDictionary Source="ReadOnlyHighPerformanceStyle.xaml" />
</igDP:XamDataGrid.Resources>

Efecto de los controles Containing en el rendimiento de XamDataGrid

Absténgase de usar efectos de mapa de bits en controles que contengan XamDataGrid o en elementos XamDataGrid. Por muy atractivos que sean, estos efectos tienen un coste de rendimiento significativo.

Si colocas XamDataGrid en un control StackPanel, tendrá una región de tamaño infinito para mostrar sus registros, lo que hará que represente CellValuePresenters para todas las celdas. Aunque el StackPanel adjunto puede controlar correctamente el desplazamiento, la superficie de memoria debida al gran número de presentadores será significativa.

Tematización

Hay una cierta cantidad de sobrecarga involucrada en la determinación de las plantillas que se usarán para varios elementos. Puede obtener un beneficio de rendimiento configurando el tema que se va a usar, incluso si es el tema Aero predeterminado, como se muestra a continuación:

<igDP:XamDataGrid Theme="Aero" />

Actualización de FieldCollection

Si va a agregar o quitar campos de la colección Fields de un FieldLayout con elementos visibles en el presentador de datos, esto podría afectar negativamente al rendimiento. Al realizar varios cambios en la colección, llame siempre a BeginUpdate antes de estos cambios y a EndUpdate después de los cambios.

Eventos suprimidos

Otra forma en que los desarrolladores pueden mejorar el rendimiento es suprimiendo los eventos enrutados que saben que no van a controlar. Esto mejora el rendimiento debido a la sobrecarga en la que se incurre con los eventos enrutados en las jerarquías de elementos. También se han agregado eventos CLR directos para eventos enrutados comunes en DataPresenterBase. Se nombran con el nombre del evento enrutado seguido de "Direct", como "CellActivatedDirect", en el caso del evento enrutado "CellActivated". Esto le permite suprimir el evento enrutado y seguir controlando su equivalente directo.

Para suprimir eventos, agréguelos a la colección DataPresenterBase.SuppressedEvents, tal como se implementó en el proyecto de ejemplo y también se muestra a continuación:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:igDP="http://infragistics.com/DataPresenter"
    xmlns:igED="http://infragistics.com/Editors"
    Title="Window1" Height="600" Width="800">
    <Grid>
        <igDP:XamDataGrid>
            <igDP:XamDataGrid.SuppressedEvents>
                <igDP:RoutedEventWrapper RoutedEvent="igED:ValueEditor.TextChanged" />

…
                <igDP:RoutedEventWrapper RoutedEvent="igED:ValueEditor.ValueChanged" />
            </igDP:XamDataGrid.SuppressedEvents>
        </igDP:XamDataGrid>
    </Grid>
</Window>

Modo de tamaño de grabación

La propiedad de modo FieldLayoutSettings.DataRecordSizing controla la forma en que se cambia el tamaño y el tamaño de los registros de XamDataGrid. Esta propiedad tiene un efecto en el rendimiento, ya que controla si cada fila tiene un tamaño independiente o si las filas tienen la misma altura.

Los valores Fixed y SizableSynchronized de esta propiedad dan como resultado filas de igual altura. Estas dos configuraciones ofrecen la mayor ventaja de rendimiento, ya que XamDataGrid puede diseñar filas de igual altura más rápido que las filas de diferente altura, que requieren recursos adicionales durante la operación de diseño.

Los valores SizedToContentAndFixed y SizeToContentAndIndividuallySizable para FieldLayoutSettings.DataRecordSizing pueden dar lugar a filas de tamaño diferente. Aunque esta configuración ofrece cierta flexibilidad en el diseño, requiere recursos adicionales en el diseño, lo que tiene un impacto negativo en el rendimiento de XamDataGrid al desplazarse.

Setting Scrolling Mode

El comportamiento predeterminado de desplazamiento del pulgar de XamDataGrid es el desplazamiento diferido con una información sobre herramientas que contiene el valor de la columna (que se puede especificar mediante la propiedad IsScrollTipField) para el registro que se va a mostrar. Esto le permite localizar rápidamente el registro que está buscando utilizando su valor en una columna determinada, en lugar de hacer una pausa en el desplazamiento para buscar el valor de la columna de registro actual.

Puede habilitar el desplazamiento inmediato estableciendo la propiedad ScrollingMode en Immediate. A diferencia del desplazamiento diferido, el desplazamiento inmediato requiere que los registros en la posición de desplazamiento correspondiente se muestren en su totalidad. Este enfoque da como resultado la manipulación de muchos elementos visuales en rápida sucesión, lo que afecta negativamente al rendimiento. Debido a esto, absténgase de usar el modo de desplazamiento inmediato tanto como sea posible, a menos que tenga un requisito específico para hacerlo.

Adjusting Cell Presenter Virtualization

Puede controlar cómo XamDataGrid virtualiza sus presentadores de registros y celdas, estableciendo las propiedades RecordContainerGenerationMode y CellContainerGenerationMode. Analizaremos las diferentes estrategias de virtualización, sus implicaciones de espacio y tiempo, y los escenarios para los que son útiles.

Reciclar

De forma predeterminada, XamDataGrid recicla los presentadores que usa: solo inicializa los presentadores para los registros o celdas visibles que luego se reutilizan a medida que se desplaza la vista. Este modo de almacenamiento en caché está optimizado para la exploración general de datos, minimizando la huella de memoria, a expensas del aspecto del tiempo. Aunque este enfoque conserva la memoria y funciona bien en la mayoría de los casos, puede dar lugar a un desplazamiento menos que perfecto, especialmente con editores como XamDateTimeEditor que contienen una jerarquía de elementos compleja.

PreLoad

Imaginemos un escenario en el que tiene muchas columnas con editores complejos, como XamDateTimeEditors, y necesita un desplazamiento horizontal rápido para mostrar las columnas adicionales. Con la estrategia de precarga, XamDataGrid inicializa los presentadores de todas las celdas que se van a mostrar, lo que garantiza una experiencia de desplazamiento fluida, a costa de un mayor tiempo de carga inicial y espacio de memoria. La configuración de Precarga es adecuada para escenarios en los que tiene un número relativamente pequeño de filas (al establecer RecordContainerGenerationMode) o columnas (al establecer CellContainerGenerationMode), de lo contrario, el tiempo de carga y la superficie de memoria pueden ser notables.

LazyLoad

Es posible que esté implementando un escenario en el que tenga una cantidad relativamente pequeña de registros y una gran cantidad de columnas, y el usuario no siempre examine todas las columnas. En este caso, puede minimizar la superficie de memoria al tiempo que garantiza una buena velocidad de desplazamiento para las columnas que ya se han puesto a la vista inicializando los presentadores de las columnas solo una vez, cuando se visualizan, y almacenándolas en caché para mejorar el desplazamiento una vez que se visualizan por segunda vez. Esto da como resultado un tiempo de carga inicial pequeño, una superficie de memoria que contiene presentadores para todas las celdas que se han puesto a la vista desde la carga de XamDataGrid (no todas, como en el caso de la estrategia PreLoad) y una penalización del rendimiento de desplazamiento solo la primera vez que se visualiza una celda. Mostrar las mismas celdas por segunda vez será rápido, ya que sus presentadores se habrían almacenado en caché la primera vez que se mostraron.

Hierarchies

Con el fin de mejorar el rendimiento, XamDataGrid usa de forma predeterminada un único panel para mostrar los registros primarios y secundarios. Esto tiene los siguientes inconvenientes:

  • Los registros anidados no están rodeados por cromo
  • Se omitirán los desencadenadores de la plantilla de un objeto RecordPresenter que se ocupa de registros anidados
  • Se omitirá la animación de la plantilla de un objeto RecordPresenter que se ocupa de registros anidados

Si desea usar alguna de las características enumeradas anteriormente, puede usar varios paneles anidados estableciendo la propiedad UseNestedPanels de GridViewSettings en true. Hay disponible información adicional sobre los registros jerárquicos y el rendimiento.

Resumen

En esta entrada de blog, analizamos varias formas de ajustar el rendimiento de XamDataGrid. Tenga en cuenta y utilícelos la próxima vez que compile su aplicación, teniendo en cuenta los requisitos de temática y estilo, así como las limitaciones de memoria y tiempo.

Solicitar una demostración