Using the xamGrid with Virtual Collections and MVVM

Have you ever wanted to build an application that uses the Infragistics Silverlight xamGrid which supports sorting, filtering, CRUD operations and data virtualization all constructed with the Model View View-Model (MVVM) pattern? This post details some of the nuances involved with building an interactive grid experience while using the Infragistics Virtual Collection to handle common data scenarios all using MVVM.

Construction

The application in this example uses the Infragistics Silverlight xamGrid control for displaying data, which is obtained through a WCF service. There data source is virtualized on the client side, which is responsible for requesting required data from the WCF service. The logic at the server is responsible filtering and sorting before sending data to the client as well as data persistence.

This post demonstrates how to create the view of the application, containing all visual elements of the UI – a xamGrid control and a button for removing records. User interaction with the UI triggers commands, which are handled in the View-Model. The View-Model part of the application transfers the data requests to the server (via the WCF service) which is responsible for handling received data. The model is defined on the server and contains entity objects definitions, WCF service handlers and sends message to the persistence layer. The data is currently persisted in MS Access data base (.mdf file).

The following screenshot is an example of the running application:

As is customary with MVVM construction, instead of writing interaction logic in the code behind file, the xamGrid events triggers commands which are ultimately handled in the view model. This approach ensures that the view is completely separated from the view model and the connection between the two classes is facilitated exclusively through the commands.

The xamGrid is bound to the page data context, which in fact is the virtualized data source defined in the View-Model. The data source is instantiated in XAML:

Code Snippet
  1. <navigation:Page x:Class="MVVM_CRUD_Virtualization.View.MainPage"
  2.     ...
  3.     xmlns:vm="clr-namespace:MVVM_CRUD_Virtualization.ViewModel"
  4.     ...
  5.     >

 

Code Snippet
  1. <navigation:Page.DataContext>
  2.     <vm:VirtualizedDataSource />
  3. </navigation:Page.DataContext>

 

Commands

The next step is to configure the xamGrid events to use commands and pass argument information to the command handler:

Code Snippet
  1. <navigation:Page x:Class="MVVM_CRUD_Virtualization.View.MainPage"
  2.     ...
  3.     xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
  4.     ...
  5.     >

 

Code Snippet
  1. <ig:XamGrid x:Name="xamGrid" ItemsSource="{Binding}">
  2.     <i:Interaction.Triggers>
  3.         <i:EventTrigger EventName="Filtering">
  4.             <i:InvokeCommandAction
  5.                 Command="{Binding Path=FilterCommand}"
  6.                 CommandParameter="{Binding ElementName=xamGrid, Path=FilteringSettings.RowFiltersCollection}"
  7.             />
  8.         </i:EventTrigger>
  9.         ...
  10.     </i:Interaction.Triggers>
  11. ...
  12. </ig:XamGrid>

 

Note:
The other relevant events and commands are defined in similar way and the full code listing is available in the accompanying code that you may download here.

The same approach is available to make a button to trigger a command:

Code Snippet
  1. <Button Content="Delete Selected Row"
  2.     Command="{Binding DeleteRowCommand}"  
  3.     CommandParameter="{Binding ElementName=xamGrid, Path=SelectionSettings.SelectedRows}" />

Handling Commands

All the commands triggered by the UI are handled in the View-Model. Most commands are executing as asynchronous operations using the WCF services for retrieving or updating operations. There is a class “DelegateCommand”, which is implementing the “ICommand” interface and used to instantiate the supported by the View-Model commands.

This is an example of how the Filter command and its handler are defined in the”VirtualizedDataSource” class, which is the View-Model of the application.

Note:
To make the code snippet small and readable the command handler implementation is omitted, but are available in the accompanying code download.

Code Snippet
  1. public DelegateCommand FilterCommand { get; set; }
  2.  
  3. public bool CanGridFilter(object parameter)
  4. {
  5.     return true;
  6. }
  7.  
  8. public void Filtering(object parameter)
  9. {
  10.     // handle the command here...
  11.     RowFiltersCollection filters = parameter as RowFiltersCollection;
  12.     ...
  13. }

CRUD operations

The CRUD (Create, Read, Update and Delete) operations are quite straightforward. The xamGrid fires events when data is changed and this triggers the associated commands. The command handlers in the View-Model are processing the command arguments and create more simple classes (like dictionaries and collection), which are later send using WCF service to the Model on the server.

In the accompanying sample, data is persisted in an Access database file, but your implementation may include any type of persistence mechanism. The comments in the source file provide more explanation of the code execution order and logic.

Filtering

When the filter conditions are changed on the xamGrid, the Filtering event is fired and then the Filtering command is triggered. The handler of the command obtains filtering conditions from the grid and adds them to the “FilterConditions” collection of the Virtual Collection. This action forces the Virtual Collection to request new data items according the new filtering condition by invoking the ItemDataRequested method. This method is executed as an asynchronous request fetching filtered data items from the WCF service.

As discussed in the help topics, the VirtualCollection is not responsible for any kind of data filtering or sorting. These features are responsibilities of the data providing logic on the server. For simplicity of this example only one kind of filtering is implemented – the “start with” filtering type. Different filtering types are just not in the scope of the current article, but they can be implemented additionally without need of changing the application’s architecture.

Sorting

When the user clicks on the grid columns to change the data sorting order, the xamGrid automatically provides these changes to the Virtual Collection, which is requesting new data items based on the new conditions. The Virtual Collection invokes the ItemDataRequested method, which asynchronously requests sorted data items from the WCF service.

Conclusion

Although your situation may not require all the functionality described in this examples, this sample demonstrates that all these fancy words and abbreviations like “MVVM”, “Virtualization”, “CRUD”, “Filtering” and “Sorting” can work together.

The solution with further code comments is available for download here.


Add a Comment

Be the first one to add a comment. Please Login or Register to add comment.