I think this topic is quite important and quite unanswered even on English-speaking blogs, so I decided to publish this entry in english… sorry French frogs!

So, a couple of weeks ago, Nikhil Kothari has written a very interesting blog post about encapsulating a RIA Services DomainContext into a ViewModel. The only feature that were not covered by the blog post was server-side paging and sorting without exposing the DomainContext and without using a DomainDataSource.

DomainDataSource is a control that encapsulate a DomainContext to provide an ICollectionView and IPagedCollectionView implementation which will be used by the RIA controls (DataGrid, DataPager…). This implementation does trigger a roundtrip to the server when the user ask for a sort or paging operation (using DataGrid headers, or DataPager control).

In a comment of his blog, Nikhil exposed a very interesting idea to make server-side paging / sorting work with a ViewModel : Implement a control similar to the DomainDataSource, but encapsulating a custom ViewModel. I have been thinking about this for a couple of days, and I implemented something that does that using reflection.

Here is the usage :

<SStuff_Ria:PagingObjectProvider x:Name="pagingObjectProvider" 
                                 DataSource="{Binding Mode=OneWay}" 
                                 GoToPageMethodName="LoadProductsPage" 
                                 ItemsSourcePropertyName="Products" 
                                 PageChangingPropertyName="PageChanging" 
                                 PageIndexPropertyName="PageIndex" 
                                 TotalItemCountPropertyName="TotalItemCount" />

(of course, the DataContext is an instance of my ViewModel, which exposes the specified methods and properties, and implements INotifyPropertyChanged).

After that, we can reference this DataSource as we did with the DomainDataSource:

<data:DataGrid Grid.Row="1"
             
IsReadOnly="True"
             
ItemsSource="{Binding ElementName=pagingObjectProvider,Path=Data}"
             
AutoGenerateColumns="False">
    <
data:DataGrid.Columns>
        …
    </data:DataGrid.Columns>
</
data:DataGrid>

<dataControls:DataPager Grid.Row="2" 
                        Source="{Binding ElementName=pagingObjectProvider, Path=Data}"/>

One really cool side effect, is that the PagingObjectProvider does not depends on RIA Services at all and could be used with custom WCF Services or with ADO.Net Data Service. So we will be able to use it as soon as SL3 is out (no need to wait for a RIA Services RTW).

Here are the sources (with 2 samples : One with RIA Services and one with custom WCF Service) : SStuff.RIA.zip