A collection providing paging, sorting, grouping and filtering of query results.
The EntityQueryPagedCollectionView can be used from code behind, and view models in MVVM architectures, to provide paged results to bound controls. It is also used internally by the ObjectDataSource when declarative specification in XAML is wanted.

The EntityQuery provided in the constructor will be executed asynchronously as needed to fulfill each paging request. Note that unless a CacheOnly query strategy is defined, the first time a page is loaded it will use a DataSourceOnly fetch strategy. Subsequent executions will use the QueryStrategy defined on the query. Note that the query must be an EntityQuery, you can't use this collection with a StoredProcQuery or PassthruEsqlQuery. For those queries, use the .NET PagedCollectionView instead.

The EntityManager of the query is used to perform query execution. If none is specified an exception is thrown. If the EntityManager is not logged in, an asynchronous login with null credentials is performed.

To use with a DataPager control, set or bind its Source property to an instance of the EntityQueryPagedCollectionView.

Inheritance: IPagedCollectionView, ICollectionView, IEditableCollectionView, INotifyPropertyChanged
    private void InitializePagedView() {

      // Let's look at all customers. The query can be of any complexity, but must be an EntityQuery<T>.  
      // If the query contains an OrderBy, that sort order will always be primary and any sort columns
      // selected by the user in the grid will be added as "ThenBy" clauses when sorting the results.

      // Don't execute the query (unless you do want the view to work with CacheOnly paging queries).  
      // The EntityQueryPagedCollectionView (PCV) will execute paged queries, first DataSourceOnly to load
      // the page, and then using the QueryStrategy in effect for the query or EM.

      // We haven't logged in with this EntityManager, so the PCV will do an implicit login with null
      // credentials before executing the query.  If you require real login credentials, then you should
      // be sure to login the EM first.

      // We're deferring the load here to add a SortDescription (instead of an OrderBy on the query).
      // Once the SortDescription is set we can load the view.

      var query = _entityManager.Customers;

      View = new EntityQueryPagedCollectionView(
               query,                  // Source of data
               PageSize,               // Page size
               PageSize,               // Load size - no lookahead caching here 
               true,                   // Whether to defer the load
               false);                 // Whether to add primary key to sort columns

      // Listen for errors now - we can catch connection/login errors when refresh occurs.
      View.PageLoadError += pcv_PageLoadError;

      // Set a sort column here - user choices in grid will override.
      View.SortDescriptions.Add(new SortDescription("CompanyName", ListSortDirection.Ascending));
      View.Refresh();

      // Listen for a few events.
      View.PageChanging += PageChanging;
      View.CurrentChanged += CurrentItemChanged;
    }
    private void LoadView() {
      // Create and start loading the PCV.

      // Neither EQPCV nor PCV will work with anonymous types.
      if (AnonymousFns.IsAnonymousType(Query.ElementType)) {
        throw new NotSupportedException("Anonymous types are not currently supported.  To work around this limitation, you can instead project into a custom type.");
      }

      if (IsEntityQuery) {
        EntityManager.GetEntityGroup(Query.ElementType).EntityChanged += ObjectDataSource_EntityChanged;
      }

      IsLoadingData = true;
      HasChanges = false;

      // Convert from our "descriptors" to the "descriptions" known by a PCV.
      var sortFields = new SortDescriptionCollection();
      SortDescriptors.ForEach(s => sortFields.Add(s.ToSortDescription()));
      var groupFields = new ObservableCollection<GroupDescription>();
      GroupDescriptors.ForEach(g => groupFields.Add(g.ToGroupDescription()));

      // We'll use an EQPCV or PCV depending on a few factors: 1) an EntityQuery (so we can issue skip/take, 2) paging
      bool useEqpcv = Query is EntityQuery && PageSize > 0;

      if (useEqpcv) {
        EntityQueryPagedCollectionView pcv = null;
        var query = Query as EntityQuery;
        var filter = GetQueryFilter();
        if (sortFields.Count > 0 || groupFields.Count > 0) {
          pcv = new EntityQueryPagedCollectionView(query, PageSize, LoadSize, sortFields, groupFields, filter);
        } else {
          pcv = new EntityQueryPagedCollectionView(query, PageSize, LoadSize, true, true);
          pcv.SetQueryFilter(filter);
          pcv.Refresh();
        }
        Data = pcv;
        DataView = pcv;

      } else {
        // Use the standard PagedCollectionView (when paging isn't wanted or not an EntityQuery)
        IEntityQuery query = Query;
        if (Query is EntityQuery) {
          query = GetFilteredQuery();
        }
        EntityManager.ExecuteQueryAsync(query, args => {
          PagedCollectionView pcv = new PagedCollectionView(args.Results);
          sortFields.ForEach(d => pcv.SortDescriptions.Add(d));
          groupFields.ForEach(d => pcv.GroupDescriptions.Add(d));
          pcv.PageSize = PageSize;
          Data = pcv;
          DataView = pcv;
        });
      }
    }