{"id":350,"date":"2010-10-26T08:50:00","date_gmt":"2010-10-26T08:50:00","guid":{"rendered":"https:\/\/staging.infragistics.com\/blogs\/?p=350"},"modified":"2025-02-25T13:38:58","modified_gmt":"2025-02-25T13:38:58","slug":"xamdatagrid-performance","status":"publish","type":"post","link":"https:\/\/www.infragistics.com\/blogs\/xamdatagrid-performance","title":{"rendered":"Optimizing Infragistics XamDataGrid Performance"},"content":{"rendered":"\n<p>The XamDataGrid component, one of the controls in the NetAdvantage for WPF Line of Business product (free trial version available here) is the most frequently-used component from our WPF product. It presents your tabular data, and allows you to group, sort, filter, compute column summaries, as well as control its layout by column grouping, reordering, pinning and many more.<\/p>\n\n\n\n<p>The <a href=\"\/products\/wpf\/grids-and-lists\/data-grid\">XamDataGrid<\/a> is also capable of handling real-time data updates and large volumes of data efficiently. In such scenarios, <a href=\"\/products\/wpf\/grids-and-lists\/data-grid\">XamDataGrid<\/a> performance is critical to the usability of your application. This is why in this post, we\u2019ll look at what you can do to maximize its performance.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"built-in-optimizations\">Built-In Optimizations<\/h2>\n\n\n\n<p>The <a href=\"\/products\/wpf\/grids-and-lists\/data-grid\">XamDataGrid<\/a> uses a variety of methods internally to make sure you\u2019re getting the best performance \u2013 it reuses presenter elements at both the record and cell level, caches style information, uses deferred tooltip scrolling and lazy object creation. A more specific <a href=\"\/help\/wpf\/xamdata-performance-optimizations-overview\">information on performance optimizations<\/a> is available. However, all of these optimizations have already been built into the control and come out-of-the box at no cost.<\/p>\n\n\n\n<p>So, what are the ways you can improve performance? I\u2019ve put together a list of points you might consider using, most of which are implemented in the sample project. I\u2019ve tried to provide as much information on how these strategies impact how your application looks or behaves, so you can consider your scenario\u2019s specific requirements and make an informed decision about which ones to use.<\/p>\n\n\n\n<p><strong>Binding to pre-formatted values<\/strong><\/p>\n\n\n\n<p>One way to improve performance in read-only columns is to reduce value formatting. Often value formatting is implemented using convertors, because it&#8217;s an easy and clean way to encapsulate formatting logic. However, when scrolling, the grid causes the converter logic to be invoked each time a cell is brought into view &#8211; when scrolling horizontally to bring a new column into view, the converter is invoked a number of times equal to the number of visible rows. The overhead of this processing is increased when using real-time updates. One way to reduce the load is to perform the value formatting in code, and bind the grid to the formatted result, which is computed just once. Furthermore, using a lazy approach, a value can be formatted once and then cached, essentially removing any need for formatting to be triggered by the UI.&nbsp;<\/p>\n\n\n\n<p>Let&#8217;s say you have a Product business object with a Price value you&#8217;d like to format in a specific way. One way to do that is to extend the original Product using a FormattedProduct, which adds a PriceFormatted property, which is computed when it is requested, and stored for later requests. If there&#8217;s a relative small number of unique values, one way to further reduce the space requirement of this caching approach is to use a dictionary for formatted values.<\/p>\n\n\n\n<p>Then, once you bind to a list of these FormattedProducts, you need to prevent the Price column from being shown, and to change the header of the PriceFormatted column, which will show its formatted values. You can do that in the event handler of the FieldLayoutInitialized event, where you can set the Visibility of the Price column to Collapsed, and the Label property of the PriceFormatted to &#8216;Price&#8217;.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"styling\">Styling<\/h2>\n\n\n\n<p><strong>Hoverless Styles<\/strong><\/p>\n\n\n\n<p>A substantial performance boost can be achieved by setting a style which refrains from applying coloring and effects in the most-frequently used visual elements. One such example is not setting any coloring to the row being hovered. Please download the high-performance XamDataGrid hoverless style. Of course, you might want to keep using some of these styling properties, and you may modify it to suit your needs. Add ths file to your project, and reference it from the XamDataGrid as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;igDP:XamDataGrid.Resources>\n   &lt;ResourceDictionary Source=\"HoverlessStyles.xaml\" \/>\n&lt;\/igDP:XamDataGrid.Resources><\/pre>\n\n\n\n<p><strong>Minimalist Styles<\/strong><\/p>\n\n\n\n<p>When you\u2019re defining your own templates for elements which appear many times in the visual hierarchy, such as <a href=\"\/help\/wpf\/xamdata-cells-cellvaluepresenters-and-cell-virtualization\">CellValuePresenters<\/a>, try and use as few elements as possible. A template will be initialized for all <a href=\"\/help\/wpf\/xamdata-cells-cellvaluepresenters-and-cell-virtualization\">CellValuePresenters<\/a> in view, which can cause the total number of visual elements to increase rapidly, having an adverse effect on performance. A more detailed explanation on the <a href=\"\/help\/wpf\/xamdata-impact-styles-have-on-performance-of-controls\">impact of styles on performance<\/a> is available. The minimal CellValuePresenter consists of a Border enclosing a TextBlock. An important detail needed to improve performance when using the minimalist style is to set the ForceCellVirtualization property (new in 11.1) to true. Add this minimalist style file to your project, and reference it from the&nbsp;XamDataGrid&nbsp;as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;igDP:XamDataGrid.Resources>\n   &lt;ResourceDictionary Source=\"ReadOnlyHighPerformanceStyle.xaml\" \/>\n&lt;\/igDP:XamDataGrid.Resources><\/pre>\n\n\n\n<p><strong>Effect of Containing controls on XamDataGrid Performance<\/strong><\/p>\n\n\n\n<p>Please refrain from using Bitmap Effects in controls containing the XamDataGrid, or in XamDataGrid elements. However appealing, such effects come at a significant performance cost.<\/p>\n\n\n\n<p>If you place the XamDataGrid in a StackPanel control, it will have an infinite size region to display its records, which will cause it to render <a href=\"\/help\/wpf\/xamdata-cells-cellvaluepresenters-and-cell-virtualization\">CellValuePresenters<\/a> for all cells. Although scrolling may be correctly handled by the enclosing StackPanel, the memory footprint due to the large number of presenters will be significant.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"theming\">Theming<\/h2>\n\n\n\n<p>There is a certain amount of overhead involved in determining the templates to be used for various elements. You can derive a performance benefit by setting the theme to be used, even if it\u2019s the default Aero theme, as shown below:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;igDP:XamDataGrid Theme=\"Aero\" \/><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"updating-the-fieldcollection\">Updating the FieldCollection<\/h2>\n\n\n\n<p>If you are adding or removing fields from the Fields collection of a <a href=\"\/help\/wpf\/xamdata-assigning-a-fieldlayout\">FieldLayout<\/a> with elements visible in the data presenter, this could adversely impact performance. When making multiple changes to the collection, always call BeginUpdate before these changes and EndUpdate after the changes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"suppressed-events\">Suppressed Events<\/h2>\n\n\n\n<p>Another way developers can improve performance is by suppressing routed events they know they will not be handling. This improves performance due to the overhead incurred with routed events in element hierarchies.&nbsp;There are also direct CLR events added for common routed events on the DataPresenterBase. They are named with the name of the routed event followed by &#8220;Direct&#8221;, such as &#8220;CellActivatedDirect&#8221;, in the case of the &#8220;CellActivated&#8221; routed event. This allows you to suppress the routed event and still handle its direct equivalent.<\/p>\n\n\n\n<p>In order to suppress events, add them to the DataPresenterBase.SuppressedEvents collection, as implemented in the sample project and also shown below:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;Window\n\u00a0\u00a0\u00a0 xmlns=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation\"\n\u00a0\u00a0\u00a0 xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\"\n\u00a0\u00a0\u00a0 xmlns=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation\"\n\u00a0\u00a0\u00a0 xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\"\n\u00a0\u00a0\u00a0 xmlns:igDP=\"http:\/\/infragistics.com\/DataPresenter\"\n\u00a0\u00a0\u00a0 xmlns:igED=\"http:\/\/infragistics.com\/Editors\"\n\u00a0\u00a0\u00a0 Title=\"Window1\" Height=\"600\" Width=\"800\">\n\u00a0\u00a0\u00a0 &lt;Grid>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;igDP:XamDataGrid>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;igDP:XamDataGrid.SuppressedEvents>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;igDP:RoutedEventWrapper RoutedEvent=\"igED:ValueEditor.TextChanged\" \/>\n\n\u2026\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;igDP:RoutedEventWrapper RoutedEvent=\"igED:ValueEditor.ValueChanged\" \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/igDP:XamDataGrid.SuppressedEvents>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/igDP:XamDataGrid>\n\u00a0\u00a0\u00a0 &lt;\/Grid>\n&lt;\/Window><\/pre>\n\n\n\n<p><strong>Record Sizing Mode<\/strong><\/p>\n\n\n\n<p>The FieldLayoutSettings.DataRecordSizing mode property controls the way the records in the XamDataGrid are sized and resized. This property has an effect on performance because it controls whether each row is sized separately or the rows are of equal height.<\/p>\n\n\n\n<p>The Fixed and SizableSynchronized values for this property result in rows of equal height. These two settings offer the biggest performance advantage, as the XamDataGrid can layout equi-height rows quicker than rows of different height, which require additional resources during the layout operation.<\/p>\n\n\n\n<p>The SizedToContentAndFixed and SizedToContentAndIndividuallySizable values for the&nbsp;FieldLayoutSettings.DataRecordSizing&nbsp;may result in rows of different size. Although these settings offer a certain amount of flexibility in layout, they require additional resources in the layout, thus having a negative impact the XamDataGrid performance when scrolling.<\/p>\n\n\n\n<p><strong>Setting Scrolling Mode<\/strong><\/p>\n\n\n\n<p>The default thumb scrolling behavior of the <a href=\"\/products\/wpf\/grids-and-lists\/data-grid\">XamDataGrid<\/a> is deferred scrolling with a tooltip containing the column value (which you can specify using the <a href=\"\/help\/wpf\/infragisticswpf.datapresenter~infragistics.windows.datapresenter.field~isscrolltipfield\">IsScrollTipField<\/a> property) for the record that will be brought into view. This allows you to quickly locate the record you\u2019re looking for using its value in a particular column, rather than pause scrolling to look for the current record column value.<\/p>\n\n\n\n<p>You can enable immediate scrolling by setting the <a href=\"\/help\/wpf\/xamdata-displaying-tooltips-while-scrolling-the-grid\">ScrollingMode<\/a> property to Immediate. Unlike deferred scrolling, immediate scrolling requires that the records at the corresponding scroll position are shown in their entirety. This approach results in the manipulation of many visual elements in rapid succession, negatively impacting performance. Because of this, please refrain from using immediate scrolling mode as much as possible, unless you have a specific requirement to do so.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"adjusting-cell-presenter-virtualization\">Adjusting Cell Presenter Virtualization<\/h2>\n\n\n\n<p>You can control how the <a href=\"\/products\/wpf\/grids-and-lists\/data-grid\">XamDataGrid<\/a> virtualizes its record and cell presenters, by setting the RecordContainerGenerationMode and CellContainerGenerationMode properties. We\u2019ll go through the different virtualization strategies, their space and time implications, and the scenarios they\u2019re useful for.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"recycle\">Recycle<\/h2>\n\n\n\n<p>By default, the <a href=\"\/products\/wpf\/grids-and-lists\/data-grid\">XamDataGrid<\/a> recycles the presenters it uses \u2013 it only initializes presenters for the visible records\/cells which are then reused as the view is scrolled. This mode of caching is optimized for general browsing of data minimizing the memory footprint, at the expense of the time aspect. Although this approach conserves memory and works well in most cases, it can result in less than perfect scrolling, especially with editors such as <a href=\"\/help\/wpf\/xamdatetimeeditor\">XamDateTimeEditor<\/a> containing a complex element hierarchy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"preload\">PreLoad<\/h2>\n\n\n\n<p>Let\u2019s imagine a scenario where you have many columns with complex editors such as <a href=\"\/help\/wpf\/xamdatetimeeditor\">XamDateTimeEditors<\/a>, and you require quick horizontal scrolling to bring any extra columns into view. Using the PreLoad strategy, the <a href=\"\/products\/wpf\/grids-and-lists\/data-grid\">XamDataGrid<\/a> initializes presenters for all the cells to be shown ensuring a smooth scrolling experience, at the cost of an increased initial loading time and memory footprint. The PreLoad setting is appropriate for scenarios where you have a relatively small number of rows (when setting RecordContainerGenerationMode) or columns (when setting CellContainerGenerationMode), otherwise the loading time and memory footprint can become noticeable.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"lazyload\">LazyLoad<\/h2>\n\n\n\n<p>You may be implementing a scenario where you have a relatively small amount of records, and a large amount of columns, and the user does not always look through all the columns. In this case, you can minimize the memory footprint while ensuring a good scrolling speed for columns that have already been brought into view by initializing presenters for columns only once \u2013 when they are brought into view, and caching them to improve scrolling once these are brought into view for a second time. This results in a small initial loading time, a memory footprint containing presenters for all cells that have been brought into view since the loading of the <a href=\"\/products\/wpf\/grids-and-lists\/data-grid\">XamDataGrid<\/a> (not all, as in the case of the PreLoad strategy), and a scrolling performance penalty only the first time a cell is brought into view. Bringing the same cells into view a second time will be fast, as their presenters would have been cached the first time they were shown.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"hierarchies\">Hierarchies<\/h2>\n\n\n\n<p>In order to improve performance, the <a href=\"\/products\/wpf\/grids-and-lists\/data-grid\">XamDataGrid<\/a> by default uses a single panel for displaying parent and child records. This has the following drawbacks:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Nested records are not surrounded by chrome<\/li>\n\n\n\n<li>Triggers in a <a href=\"\/help\/wpf\/infragisticswpf.datapresenter~infragistics.windows.datapresenter.recordpresenter\">RecordPresenter<\/a> object\u2019s template dealing with nested records will be ignored<\/li>\n\n\n\n<li>Animation in a RecordPresenter object\u2019s template dealing with nested records will be ignored<\/li>\n<\/ul>\n\n\n\n<p>If you would like to use any of the features listed above, you can use multiple nested panels by setting the UseNestedPanels property of the <a href=\"\/help\/wpf\/infragisticswpf.datapresenter~infragistics.windows.datapresenter.gridviewsettings\">GridViewSettings<\/a> to true. Additional information on <a href=\"\/help\/wpf\/xamdatapresenter-hierarchical-records-and-performance\">hierarchical records and performance<\/a> is available.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"summary\">Summary<\/h2>\n\n\n\n<p>In this blog post, we looked at a number of ways to fine-tune <a href=\"\/products\/wpf\/grids-and-lists\/data-grid\">XamDataGrid<\/a> performance. Please consider and use these next time you\u2019re building your application, keeping in mind your theming, styling requirements, as well as your memory and time constraints.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The XamDataGrid component, one of the controls in the NetAdvantage for WPF Line of Business product (free trial version available here) is the most frequently-used component from our WPF product. It presents your tabular data, and allows you to group, sort, filter, compute column summaries, as well as control its layout by column grouping, reordering, pinning and many more. <\/p>\n","protected":false},"author":94,"featured_media":2370,"comment_status":"publish","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[],"class_list":["post-350","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to"],"_links":{"self":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/350","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/users\/94"}],"replies":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/comments?post=350"}],"version-history":[{"count":3,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/350\/revisions"}],"predecessor-version":[{"id":2223,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/350\/revisions\/2223"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/media\/2370"}],"wp:attachment":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/media?parent=350"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/categories?post=350"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/tags?post=350"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}