We are seeing that in some scenarios there is a much higher cost to re-bind the DataSource of a XamDataGrid. It seems, based on profiling traces, that all the time is spent in RemoveLogical/VisualChild downstack from GridViewPanelFlat+GenerationCache.Dispose() and AddLogicalChild downstack from GridViewPanelFlat+GenerationCache.GenerateAllRecords().
We're trying to get a reduced repro of this to share but we have yet to achieve it. In our full solution it seems that these hotpaths are always being hit when re-binding DataSource. However, in the simplest fully independent scenario of a XamDataGrid and a button to effect a re-bind of the DataSource we do not see these hotpaths being hit at all. I am able to get a rather minimal repro of the Dispose side of things, so I'll focus on that for now.
The further discussion is based off of a sample I will attach. In the sample there is a window with a XamDockManager and a Button. Clicking the Button will add a view with a XamDataGrid to the DocumentContentHost of the XamDockManager. The view also has a button to refresh the data.
Attached is a screen snip illustrating the hotpaths in Dispose. The view (SampleDataView) hooks the XamDataGrid.Loaded so that it can further hook the RecyclingItemsControl.ContainerDiscarded, you can set a breakpoint in this event handler to see when containers are being discarded and therefore when we hit the hotpath.
If you simply click the "Load Data" button once and then continually click the "Reload" for the single XamDataGrid you will see that the breakpoint is never hit. This is as we would expect.
If you click "Load Data" more than once and you re-dock the tabgroups a couple times and then click "Reload" then the first reload for each will hit the hotpath. All extant containers will be discarded. From our viewpoint this shouldn't be happening, it really shouldn't be any different from the previous case.
There seems to be something that has changed internal state for the XamDatGrid and related components that causes it to discard all the containers. This is the minimal case we have found thus far that hits the hotpath. Note, however, that in our full solution the hotpath is *always* hit, not just after a re-dock operation.
Of additional note, you can see the virtualization settings in the sample project, in our full solution we are explicitly using the following:
RecordContainerGenerationMode="Recycle"
CellContainerGenerationMode="Recycle"
RecordLoadMode="PreloadRecords"
AllowCellVirtualization="True"
AllowLabelVirtualization="False"
If the attached application by Miguel is modified as below then we will get the same problem stack and containers will be discarded :
1) First clear the data source on the UI thread (grid.DataSouce=null or grid.DataSource.Collection.Clear()), followed by a background thread populating a new collection that is then attached to the grid on the UI thread.
or
2) First clear the data source on the UI thread (grid.DataSouce=null or grid.DataSource.Collection.Clear()), followed by attsching a new empty collection that is populated on a background thread.
In both cases containers are discarded because the request to clear the datasouce is queued on the Dispatcher and processed before a new non-empty collection is attached again.
Hence if the application is modified such that the grid is not cleared or/and attached to an empty collection until a new collection is populated , then the containers are not discarded. Obviously if the new collection has less records to be displayed then the previous containers that are not required will be discarded.
1) First the datasource is cleared on the UI thread (grid.DataSouce=null or grid.DataSource.Collection.Clear()), followed by a background thread populating a new collection , finishing with the attaching new collection to the grid on the UI thread.
2) First the datasource is cleared on the UI thread (grid.DataSouce=null or grid.DataSource.Collection.Clear()), then a new empty collection is attached to the grid right away while a background thread fetches the data and populates that collection.
In both cases containers are discarded because the request to clear the datasouce is queued on the Dispatcher and processed before the data can be populated and attached.
Hence if the application is now modified such that the grid is not cleared or attached to an empty collection until the new collection is populated and only then attach to the grid, then the containers are not discarded. Obviously if the new collection has less records to be displayed then the previous ones, the unused containers will be discarded.
Hello - we are facing the exact same problem. I'm not referencing to the behavior when the grid is docked from one tab pane to another. Instead when rebind the datasource, the containers get discarded and 50% of the time spent is in dispose. Same stack as mentioned in the thread above. However if we put the same code in a simple WPF application with no custom themes, and cell value presenter styles it spends MINIMAL time in dispose. One can easily see the difference visually.
Hello Miguel,
Just checking in, did you have any other questions or concerns on this matter?
Sincerely,AndrewAssociate DeveloperInfragistics Inc.www.infragistics.com/support
Thank you for your post.
The behavior you are seeing in the XamDataGrid when you re-dock a tab/pane in the XamDockManager and the ContainerDiscarded event is called is expected behavior of the grid. The reason for this is that after you dock one of the panes, the grid inside of it will presumably have less visible records than before. Records and cells that are out of view have their containers virtualized by default in the grid, and so when you click the reload button, it discards the containers that are no longer in use, and so the ContainerDiscarded event fires once for each container discarded. You can see this behavior more clearly by running your sample project and docking a tab/pane to the right or left and clicking the Reload button. The ContainerDiscarded event will only fire once, as there is a marginal record that is now out of view.
Regarding the five explicit virtualization properties that you are setting in your full solution, I am unsure why this would fire the ContainerDiscarded event every time, but I have not been able to reproduce this behavior with the sample project you sent and setting these five properties to the values you provided. Would it be possible for you to please provide more detail on what is happening in your full project so that I can reproduce this behavior you are seeing?
Regarding multiple attachments to the forums, to my knowledge the forums don't currently support that. I would recommend that you gather a copy of each of your attachments, place them all in a folder together, and then send a .zip file of that folder.
Please let me know if you have any other questions or concerns on this matter.