This is a migrated thread and some comments may be shown as answers.

Virtualization failing on data re-load

7 Answers 144 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Matt
Top achievements
Rank 1
Matt asked on 17 Oct 2013, 05:09 PM
I have a radgrid that I am working on for a client that contains about 15 columns and at times upwards of 8k rows.

The crux of my situation lies in re-generating the collection that is the ItemsSource to the RadGrid.  On first load the data comes back (1000 records at a time) and loads into the grid smooth with everything operating as desired.  Now if I go and retrieve the exact same data set (or a different one) using the same call and getting the data 1000 records at a time...the loading dialog that I have in place freezes each time a new batch of 1000 records returns, presumably because the data is being drawn in the grid.

Keep in mind that during load the visibility of the grid is set to collapsed as I was trying to optimize performance when I realized that the true issue seems to be that after initial load the virtualization turns off and the subsequent loads then draw every item returned which is less then pretty.

Any thoughts/ideas would be welcome thanks!

Sorry I cannot provide the code and at this moment do not have time to write a demo, but the main issue here is that first load is GREAT!...any load there after unless you restart the app is slower when iteratively populating the collection the ItemsSource is 'OneWay' bound to.  And all styles being used for cells are implicit as to prevent each cell needing special treatment.

7 Answers, 1 is accepted

Sort by
0
Dimitrina
Telerik team
answered on 22 Oct 2013, 02:45 PM
Hello,

Please ensure that RadGridView is not measured with Infinity as explained in
this article. Please note that in case the UI Virtualization is disabled, then all the visual elements will be loaded once RadGridView is visualized and its items are populated. Otherwize only the visible items will be populated.

As to the performance tips we can suggest - they are listed in this
help article.

Let me know if there is an improvement based on my suggestions.
 
Regards,
Didie
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Matt
Top achievements
Rank 1
answered on 22 Oct 2013, 02:58 PM

Currently the height and width are set dynamically based on the parent container.  Would it matter then if the parent container uses infinity when we look at it's rendered size and create the grid size based on that value? 

Now the behavior in this post is used to set those values respectively but it still seems that the data is being drawn as we return each 1k records.  We chose 1k because any amount of data larger and the loading hangs as it 'draws' thus our conclusion that the data is being rendered and NOT virtualized properly.  If I load ALL the data and THEN display the grid the drawing seems to take a bit less time and the load is smooth but the users would like to be able to see the records being populated allowing them to cancel at any point during the load if they see something they happen to be looking for.

So to summarize, it seems that when I make the calls and try to load 1k items into the collection that the RadGrid is bound to, it draws each 1k items whether I have height and width set or not, which in turn means each time I retrieve 1k items, the loading dialog hangs for (guessing about 1.5 seconds or so) a period and looks rather poor...Does that help?

The behavior to define height and width values is as follows:

public class SetWidthAndHeightBehavior : Behavior<RadGridView>
    {
        //TODO:  We should add dependency properties to obtain the hardcoded info in this scenario.
        //
        protected override void OnAttached()
        {
            base.OnAttached();
 
             var parent = AssociatedObject.Parent;
             var radPanelBar = AssociatedObject.FindName("searchRequest");
 
 
             if (parent == null || parent.GetType() != typeof(Grid) || ((Grid)parent).ColumnDefinitions.Count == 0)
             {
                 throw new ArgumentException("This behavior expects that the RadGridView control is wrapped in a Grid Element and is located in column two");
             }
             else
             {
                 // We are going to listen for changed that occur within the parent grid.  When the size changes we
                 // are going to set the grids width and height which will in turn allow virtualization to work
                 // when the control is placed in a stack panel, scroll viewer or something else that results in an
                 // infinity viewport scenario.
                 //
                 // Then we find the panel bar item in the grid and listen to when the
                 // panel is expanded and collapsed, when this occurs we offset that panels size on the grid to
                 // ensure the grid is sized correctly when the panel is expanded and collapsed.
                 //
                 ((Grid)parent).SizeChanged += SetWidthAndHeightBehavior_SizeChanged;
                 ((RadPanelBarItem)radPanelBar).Collapsed += SetWidthAndHeightBehavior_Collapsed;
                 ((RadPanelBarItem)radPanelBar).Expanded += SetWidthAndHeightBehavior_Expanded;
 
                 AssociatedObject.UseLayoutRounding = true;
             }
 
        }
 
        /// <summary>
        /// Handles the Expanded event of the SetWidthAndHeightBehavior control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.RadRoutedEventArgs" /> instance containing the event data.</param>
        private void SetWidthAndHeightBehavior_Expanded(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            AssociatedObject.Width = AssociatedObject.Width - 270;
        }
 
        /// <summary>
        /// Handles the Collapsed event of the SetWidthAndHeightBehavior control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.RadRoutedEventArgs" /> instance containing the event data.</param>
        private void SetWidthAndHeightBehavior_Collapsed(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            AssociatedObject.Width = AssociatedObject.Width + 270;
        }
       
        /// <summary>
        /// Handles the SizeChanged event of the SetWidthAndHeightBehavior control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs" /> instance containing the event data.</param>
        private void SetWidthAndHeightBehavior_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            Grid parent = (Grid)AssociatedObject.Parent;
 
            if (parent.ColumnDefinitions[1].Offset != 0 &&
                e.NewSize.Width - parent.ColumnDefinitions[1].Offset != 0)
            {
                AssociatedObject.Width = e.NewSize.Width - parent.ColumnDefinitions[0].Offset - parent.ColumnDefinitions[0].ActualWidth;
                AssociatedObject.Height = e.NewSize.Height - parent.RowDefinitions[0].Offset - parent.RowDefinitions[0].ActualHeight - parent.RowDefinitions[2].ActualHeight;
            }
        }
 
    }
0
Matt
Top achievements
Rank 1
answered on 22 Oct 2013, 03:42 PM
The Caveat to this is:
1.  If the grid is visible while the data is loading, virtualization seems to fail and it draws each record from each batch of 1k.
2.  If the grid is not visible until after the records have all been retrieved virtualization 'seems' to work but then if we clear the collection and retrieve new records (or the same records again for that matter) the grid, even invisible, hangs with each call when the 1k records returns as though it were visibly drawing them.

Sorry if I did not state that clearly enough before as those are the two scenarios I am fighting with currently.
0
Matt
Top achievements
Rank 1
answered on 24 Oct 2013, 05:15 PM
I presume this must be standard functionality that when re-loading a collection or re-populating a once drawn grid that virtualization is off since I still have yet to hear of a solid solution or find one.  I appreciate the suggestions though Didie, they were unsuccessful in resolving this.
0
Dimitrina
Telerik team
answered on 25 Oct 2013, 10:51 AM
Hi,


To ensure that RadGridView is not measured with Infinity, you can set a fixed Height and Width for RadGridView.

May I ask you confirm what is the collection you use? Is it a VirtualQueryableCollectionView? If so, you can also test on our "Data Virtualization" WPF Demo. Generally this collection is designed with a limited options. For more complicated case, I can suggest you to use a QueryableCollectionView and paging over it.

I am afraid that I am not sure what would be the problem with your solution. Would it be possible for you to isolate the issue in a demo project which I can debug locally? 

Regards,
Didie
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Matt
Top achievements
Rank 1
answered on 25 Oct 2013, 01:08 PM
We are using a custom collection made for the tool itself and it properly uses ObservableCollection<T> and INotifyPropertyChanged.  It contains some special logic for use after the items are loaded (and it is indeed deferred to post load so I know that is not the issue here as it was my first thought) and I know this because I triple checked.

I have quadruple checked now that the values are indeed being set and unfortunately the time involved to create a demo of this complexity (nested grids etc. to give you the full effect) would be a bit out of the realm of what my client is willing to allow.  If I can scrounge together enough time outside of that I will see what I can do for a demo.  The general idea is having a grid that has (generalizing) 15 columns, 20k rows, and it is hierarchical though the children load on demand.  Those rows consist of read only columns with the exception of 5 columns that are templated to contain dropdowns for editing purposes. 

That is all that is handled on the loading as I have pushed validation off until after the items are loaded fully so that it only fires once, as well as anything else I could defer.  Is it possible to defer the cell styling as well?
0
Dimitrina
Telerik team
answered on 28 Oct 2013, 08:56 AM
Hello,

I would suggest you to use NoXaml binaries and Implicit Styles. Then, you can also apply Lightweight Templates

Those, together with the tips in our online documentation is what we recommend. Another tip is to please make sure that you have not set DataLoadMode="Asynchronous". Using this mode can lead to some issues and it is definitely not recommended.

We just released a new version - Q3 2013, so would you please also test with it? You can also perform a test with the MS DataGrid. Is the performance much more better with it?

Regards,

Didie
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
Tags
GridView
Asked by
Matt
Top achievements
Rank 1
Answers by
Dimitrina
Telerik team
Matt
Top achievements
Rank 1
Share this question
or