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


Commentaires :

# re: [Silverlight 3] Paging with RIA controls + M-V-VM without DomainDataSource
Ecrit par Nikhil Kothari le 5/13/2009 11:52 PM
Hi Simon,

Very cool to see this!

Indeed a view model allows you to abstract the underlying machinery, which makes it work as well for WCF services as it does for RIA services.
# re: [Silverlight 3] Paging with RIA controls + M-V-VM without DomainDataSource
Ecrit par Jonathan le 7/15/2009 1:02 AM
Booya! Nice work.
# re: [Silverlight 3] Paging with RIA controls + M-V-VM without DomainDataSource
Ecrit par Alexandre le 7/25/2009 9:56 AM
Très bon travail
# re: [Silverlight 3] Paging with RIA controls + M-V-VM without DomainDataSource
Ecrit par Jonathan le 7/30/2009 6:34 PM
One thing I have noticed is that since the Data property of the PagingObjectProvider is of type "object" from the ObservableCollection that it extends, when binding to a DataGrid, it can't automatically generate the columns for you. Further, if you manually define the columns, sorting seems to be disabled on them. I am assuming this is because of the way the DataGrid sets up the DataGridColumns, automatically disabling sorting for columns it didn't find on load. In the PagingObjectProvider, if I add a hack (for testing purposes) and manually add one of my business objects to the Data collection, the Columns and automatically generated and sort just like normal.

Anybody else seen this? What are the workarounds to get sorting working?

Thanks!
# re: [Silverlight 3] Paging with RIA controls + M-V-VM without DomainDataSource
Ecrit par Jonathan le 7/30/2009 9:26 PM
I think I have found an answer to the problem. I don't know why DataGrid is so particular about an object collection, but it is. What I did to solve this was wrap up all of the properties and methods that POPCollectionView will use into a master
interface as so:

private interface IPOPCollectionView : IPagedCollectionView, INotifyPropertyChanged, ICollectionView, INotifyCollectionChanged,
IList, ICollection, IEnumerable
{
event EventHandler<RefreshEventArgs> OnRefresh;
bool IsPageChanging{
get; set;
}

int PageIndex{
get; set;
}

int TotalItemCount{
get; set;
}
}

Then I set me Data property (in PagedObjectProvider) type to the IPopCollectionView interface. I instantiate the _data instance using the MakeGenericType and the CreateInstance Method as so:

System.Type specificType = generic.MakeGenericType(new System.Type[] { innerType });
_data = (IPOPCollectionView)Activator.CreateInstance(specificType, this);

Now the DataGrid auto generates my columns and allows them to be sortable. You must add properties for the innerType in your DataSource and dynamically set them in the PagedObjectProvider, but it seems to actually work. Also, the RIA Services Load calls are outdated in the project. There is online documentation on how to call it. Hope this helps somebody.
# re: [Silverlight 3] Paging with RIA controls + M-V-VM without DomainDataSource
Ecrit par Simon le 8/12/2009 12:52 AM
In fact I did not implenent the grouping handling as it requires another quite complex behavior comportment : when you expose data as groups, the end user does not expect content of groups to be splitted accross different data-pages. So the server-side paging + grouping thing is quite difficult to implement (and even more if you want to make it generic).
# re: [Silverlight 3] Paging with RIA controls + M-V-VM without DomainDataSource
Ecrit par Williams le 8/16/2009 6:30 AM
useful script, thanks
# re: [Silverlight 3] Paging with RIA controls + M-V-VM without DomainDataSource
Ecrit par Alexandre Arnaudet le 11/25/2009 11:45 PM
j'étais déjà passé sur ce post, mais sans laisser de commentaire, donc aujourd'hui je le fais. Merci de partager ce contrôle très utile. Que ce soit cet article ou les autres notamment avec Unity, toujours aussi intéressant.
# re: [Silverlight 3] Paging with RIA controls + M-V-VM without DomainDataSource
Ecrit par Shaguf Mohtisham le 3/30/2010 11:43 PM
Scrum Master Stephen Forte Teaches Agile Development, Silverlight and BI at Great Indian Developer Summit 2010 in Bangalore from 20 April to 23 April 2010. Interested people can register at developersummit dot com
# re: [Silverlight 3] Paging with RIA controls + M-V-VM without DomainDataSource
Ecrit par Giocare alle Video Slots le 5/4/2010 3:16 AM
The Items collection of TreeView only contains the data objects represented by the root-level nodes. You must use a recursive technique to walk through the items and set the IsSelected property to true on the TreeViewItem which you want to select.....
# re: [Silverlight 3] Paging with RIA controls + M-V-VM without DomainDataSource
Ecrit par Tomas le 5/5/2010 12:35 AM
Hi,

thank you for this control, it is just what I need. It works nice but data in DataGrid are not displayed. They are loaded in Data property, but DataGrid is empty. Has anybody working example? I tried to modify it to be a generic control, but DataGrid still empty.

Help would be much appreciated.
Thanks, Tomas

Ecrire un commentaire :

Titre :*
Nom *
Email
Url
Commentaire : *  


Please add 5 and 7 and type the answer here: