VirtualQueryableCollectionView and MVVM Light

9 posts, 2 answers
  1. Saykor
    Saykor avatar
    70 posts
    Member since:
    Feb 2011

    Posted 13 May 2014 Link to this post

    Hi,
    I follow your demo: http://www.telerik.com/help/wpf/gridview-populating-datavirtualization.html and seems I missing something.

    Use code first.

    xaml:
    -------------------------------
    <telerik:RadGridView Grid.Row="1" Name="_grid" ItemsSource="{Binding Contacts}" AutoGenerateColumns="True" 
                                 ShowColumnFooters="True"
                                 ColumnWidth="*" AlternationCount="2" AlternateRowBackground="#FFEAEFF7" Background="#FFD2DEEF" EditTriggers="None"
                                 telerik:StyleManager.Theme="Summer" HorizontalGridLinesBrush="White" VerticalGridLinesBrush="White">

     <telerik:RadDataPager Grid.Row="2" Source="{Binding ElementName=_grid, Path=Items}"
                                  DisplayMode="FirstLastPreviousNextNumeric,Text" PageSize="18" />
    -------------------------------

    ViewModel:
    -------------------------------
    public VirtualQueryableCollectionView Contacts { get; set; }

    public ContactViewModel()
            {
                var db = new PaperCRMContext();
                var query = db.Contacts.OrderBy(x => x.Id);
                Contacts = new VirtualQueryableCollectionView(query) { LoadSize = 10 };
            }
    -------------------------------
    When I run the project I receive error: 
    {"There is already an open DataReader associated with this Command which must be closed first."}

    When I remove .OrderBy(x => x.Id) i receive other error: 
    {"The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'."}

    At last when I remove { LoadSize = 10 }
    I receive empty grid

    Can someone help me what I miss here?

    Best regards,
    Saykor


  2. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 14 May 2014 Link to this post

    Hello Saykor,

    You can check the "Data Virtualization" WPF Demo as a run-able example.

    Basically the code you need to execute in order to fill with data would be:
    Contacts = new VirtualQueryableCollectionView(new NorthwindEntities().Contacts.OrderBy(o => o.Id)) { LoadSize = 10 };

    Regards,
    Didie
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  3. Saykor
    Saykor avatar
    70 posts
    Member since:
    Feb 2011

    Posted 15 May 2014 Link to this post

    Thank you Didi for your fast answer but it not help. Your code is same like my code. I suppose you miss the important part from my post: I use Code First.

    Here you a simple code first project that will make a database with 100 contacts and when try to populate the grid will break.

    https://mega.co.nz/#!hk4SnLoR!u_iqpsos0mKD4jnSKpT9vXcED8AOv6-eBva0n59ENf8

    Telerik dlls version: 2013.2.611.45
    Update packages from nuget
    Change connection string

    Thank you

    Warm regards,
    Saykor

  4. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 20 May 2014 Link to this post

    Hello Saykor,

    You have not included the DataBase you have set as an Initial Catalog in ApplicationDataContext connection string. Still, I was able to run the solution and I got the error you reported:
    There is already an open DataReader associated with this Command which must be closed first.

    Then, I also got the other errors as you reported them. It seems this is depending on the way you are populating the data as I cannot reproduce the same on our WPF demo or the projects from this blog post:
    Data Virtualization for your Silverlight and WPF Applications.

    I will investigate the case further and contact you back with more information.

    As a side note, I have a comment related to setting AlternationCount. Generally when you have alternation almost every operation will be slower since the control will need to refresh all rows in the view port in order to keep alternating. So I would suggest you skipping it. 

    Regards,
    Didie
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  5. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 21 May 2014 Link to this post

    Hello,

    As it turns out the reason for this problem is that you are using the virtual collection with RadDataPager.

    The RadDataPager and the VirtualQueryableCollectionView are two different alternatives to solving the same problem. They were never meant or designed to work with each other, since it does not make sense.

    The idea of the VirtualQueryableCollectionView is to load only the items needed at the moment, i.e. those that are visible. All the items that are not in the view port are not available till you scroll to them.  In that case the user moves up and down and requests different parts of the data - there is your "paging".  

    When using the data pager it shows only one page with the loaded data and it is not aware that there are other items to be loaded. You can check this blog post describing the purpose of RadDataPager.

    So you have to use either paging or data virtualization, since there is no such architectural concept as using them in combination.

    Regards,
    Didie
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  6. Saykor
    Saykor avatar
    70 posts
    Member since:
    Feb 2011

    Posted 21 May 2014 Link to this post

    Hello Didie,

    "They were never meant or designed to work with each other, since it does not make sense"

    Can I ask why it does not make sense?

    I not want to use a infinity scroll and want to use a pagination. So what need to do? To write my own Pager Control when click on page 2 to download the next items? Webforms style ...

    It is completely sense for me the RadDataPager to download and show the data only when it is requested to be visible. Not to download all 50k records of data when user in most case will see first 2-3 pages.

    http://www.telerik.com/products/wpf/data-virtualization.aspx
    "Use VirtualQueryableCollectionView for on-demand data loading" From this I suppose it is integrated with RadDataPager too.

    You remember before years we use in webforms custom pager to download data page by page. Build few buttons with click events... etc... Now we have a model binding when can just use IQueryable<T> and grid do this.

    Is this sound sense?

    Regards,
    Saykor

  7. Answer
    Boris
    Admin
    Boris avatar
    276 posts

    Posted 26 May 2014 Link to this post

    Hello Saykor,

    As Didie mentioned the VirtualQueryableCollectionView and the DataPager are two different approaches for solving the same issue. There is no reason to combine them, because the DataPager loads as much items as the PageSize property is set to. In your case you mentioned that you would like to use paging. So you can replace the VirtualQueryableCollectionView with the QueryableCollectionView

    public class MainViewModel : ViewModelBase
        {
            public QueryableCollectionView Contacts { get; set; }
            
            public MainViewModel()
            {
                Contacts = new QueryableCollectionView(new ApplicationDataContext().Contacts.OrderBy(o => o.Id));           
            }
        }

    However, if you want to use the RadDataPager only for its UI without passing any data to it. You will need to use the RadDataPager's Unbound Mode feature.

    Also, I attached the modified sample project.

    I hope this helps.


    Regards,
    Boris Penev
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  8. Saykor
    Saykor avatar
    70 posts
    Member since:
    Feb 2011

    Posted 26 May 2014 Link to this post

    Hi Boris,
    I like your demo project but there have a few bugs. I change it to work with 1000 records not 100 and 25 records per page and RadDataPager.DisplayMode="FirstLastPreviousNextNumeric,Text"

    http://prntscr.com/3mtrdq
    If you see this picture when I start the project there have 25 records but RadDataPager show only 1 page and in right Page 1 from 4.

    When I go to page 4 hop we see all as need: http://prntscr.com/3mtrsf



  9. Answer
    Boris
    Admin
    Boris avatar
    276 posts

    Posted 29 May 2014 Link to this post

    Hello Saykor,

    In order to show more numeric buttons you will need to set NumericButtonCount property of the DataPager to the desired number of buttons. However, you will also need to bind the Source property of the DataPager to your QueryableCollectionView collection. Then bind the ItemsSource property of the GridView to the DataPager. This is needed because the DataPager doesn't seems to calculate correctly the total number of pages.

    <telerik:RadGridView Name="_grid"
                                 Grid.Row="0"
                                 AlternateRowBackground="#FFEAEFF7"
                                 AlternationCount="2"
                                 AutoGenerateColumns="True"
                                 Background="#FFD2DEEF"
                                 ColumnWidth="*"
                                 ItemsSource="{Binding ElementName=DataPager1, Path=PagedSource}"
                                 ShowColumnFooters="True" />
     
            <telerik:RadDataPager x:Name="DataPager1"
                                  Grid.Row="1"
                                  NumericButtonCount="10"
                                  DisplayMode="FirstLastPreviousNextNumeric,Text"
                                  PageSize="10"
                                  FontSize="12"
                                  BorderThickness="1,0,1,1"
                                  Source="{Binding Contacts}" />

    Also, I attached a sample project to demonstrate the suggested approach.

    i hope this helps.

    Regards,
    Boris Penev
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
Back to Top