Columns & Rows, Part V

Silverlight 2.0 DataGrid Paging and Sorting

aspFeature

Columns & Rows,
Part V

Silverlight 2.0 DataGrid Paging and Sorting

By Bilal Haidar

In any business application developed on top of Silverlight, having a DataGrid control to display data records is a must. However, displaying too many records at once can be problematic: Too many records to browse, and a user may not find what he's looking for; loading too many records may also affect performance, making an application slow to respond. Silverlight 2.0 DataGrid does not provide paging out of the box, but implementing such a feature is easy.

In the first four installments of this series, I introduced DataGrid properties and columns, editing/updating/creating data inside the DataGrid, and implementing master/detail behavior using the smart row details feature. In this article, I'll introduce you to a simple technique that will help you page records through the DataGrid and display a page at a time without having to load all records from the server. In addition, you'll be amazed by the built-in sorting feature present in the Silverlight 2.0 DataGrid that allows you to sort data based on single or multiple columns.

References to Silverlight 2.0

This article assumes a fair knowledge of using Silverlight 2.0 especially data-binding features and is not intended as an introduction to Silverlight 2.0. If you need more information about Silverlight 2.0, go to the official Silverlight website at www.silverlight.net, where you'll find dozens of articles and videos to get you started. Another major resource for learning Silverlight 2.0 is www.silverlightshow.net; it focuses on delivering rich and comprehensive Silverlight tutorials. In addition, you can download the Microsoft Silverlight 2.0 SDK Documentation, which covers all features of Silverlight (www.microsoft.com/downloads/details.aspx?familyid=BCE7684A-507B-4FC6-BC99-6933CD690CAB&displaylang=en).

Paging DataGrid Records

The Silverlight 2.0 DataGrid doesn't ship with any built-in feature that supports paging records being displayed. Several solutions have been implemented through online articles, including one that uses the RowDetailsTemplate to provide a paging navigation UI. In this article, we'll build a simple navigation UI that sits just beneath the DataGrid on a page. Figure 1 shows the final result of implementing a DataGrid, along with the navigation UI.

Figure 1

Figure 1: Output result of implementing navigation UI

You can see in Figure 1 that the DataGrid is configured to display three records at a time. The navigation UI, located under the DataGrid, shows page 1 of 3 pages, the total number of records to be displayed.

To implement this simple navigation UI, let's first add and configure a DataGrid as shown in Figure 2. This DataGrid displays three columns: FirstName, LastName, and IsMarried. The same DataGrid has been used in previous installments of this series. Figure 3 shows the XAML required to implement the navigation UI.

Without going into detail about the XAML used, let me note that the navigation UI mainly contains a TextBlock control to state which page is currently being viewed. In addition, a ComboBox control is used to contain all the pages the user can navigate to.

After the XAML page is loaded, the ComboBox control is populated with the total number of pages to be displayed:

void Page_Loaded(object sender, RoutedEventArgs e)

{

// Bind Pages' Combo

BindPageCombo();

}

The BindPageCombo() method is defined as follows:

private void BindPageCombo()

{

this.totalPages =

EmployeeManager.GetEmployeeList().Count;

this.totalPages = Convert.ToInt32(Math.Ceiling(totalPages/(double)this.pageSize));

for (int i = 0; i < this.totalPages; i++)

{

ComboBoxItem item = new ComboBoxItem();

item.Content = (i + 1);

if (i == 0)

item.IsSelected = true;

this.cmbPages.Items.Add(item);

}

}

The method starts by retrieving the total number of records to display. Based on the number of records to be displayed per page, the total number of pages is calculated. Finally, for each page number to be displayed, a corresponding ComboBoxItem object is created and added into the ComboBox control's Items collection. A simple check is performed to make sure the first item in the ComboBox control is selected.

If you look again at Figure 3, you'll notice the following:

The above XAML subscribes into the SelectionChanged event of the ComboBox control. Thus, when the first item representing page number 1 is being added to the ComboBox control's Items collection, the SelectionChanged event fires. The SelectionChanged event handler is defined as follows:

private void cmbPages_SelectionChanged(object sender, SelectionChangedEventArgs e)

{

this.pageNumber =

Convert.ToInt32((e.AddedItems[0] as ComboBoxItem).Content.ToString());

// bind the Grid

BindDataGrid();

// update toolbar

UpdatePageToolbar();

}

The SelectionChanged event handler starts by setting the value of a private member variable to the page number selected from the ComboBox control. The BindDataGrid() method is then called to bind and populate the records inside the DataGrid:

private void BindDataGrid()

{

this.dgEmployees.DataContext =

EmployeeManager.GetPagedData(this.pageNumber, this.pageSize);

}

The BindDataGrid() method issues a call to the EmployeeManager.GetPagedData() method, passing to it as input parameters the page number to retrieve and the number of records allowed to be displayed on the DataGrid.

The GetPagedData() method can be a method that issues a call to the server to retrieve the specific records required by the DataGrid. In this case, it's a simple method that queries an in-memory collection of Employee records.

The ObservableCollection returned by the GetPagedData() method is set to the DataGrid's DataContext property, binding the DataGrid to the collection of Employee objects.

Going back to the SelectionChanged event handler, once the DataGrid is bound to the data, a call to the UpdatePageToolbar() method is issued to update the page number being displayed inside the navigation UI as follows:

private const string PAGE_FORMAT = "Page {0} of {1}";

private void UpdatePageToolbar()

{

this.txtPages.Text =

string.Format(PAGE_FORMAT, this.pageNumber, this.totalPages);

}

As shown above, the TextBlock control is used to display the current page number. The page number being displayed is updated to reflect the changes to the page number selected inside the ComboBox control.

That's all you need to do to provide paging on the Silverlight DataGrid. Start by selecting a page number from the ComboBox control's Items and you'll be taken to that specific page automatically.

Stealth paging is another approach to implementing paging in the Silverlight DataGrid. In brief, stealth paging provides no navigation UI for a user to select the page to navigate to. On the contrary, while the user is scrolling through the records, more records are being loaded into the DataGrid. You can find a complete example of how to implement stealth paging in the Silverlight DataGrid by reading the article "Stealth Paging: DataGrid" (http://weblogs.asp.net/manishdalal/archive/2008/10/09/stealth-paging-datagrid.aspx).

Sorting DataGrid Columns

The Silverlight 2.0 DataGrid that shipped in December 2008 included built-in support for sorting columns. There are two kinds of sorting modes, single-column sorting and multiple-column sorting.

For the DataGrid to support sorting, the data bound should implement the IList interface. Examples of collections that implement the aforementioned interface are List and ObservableCollection collections. This requirement is a must because under the hood DataGrid wraps the collection implementing the IList interface into a ListCollectionView collection to provide sorting functionality. Given the fact that any collection implementing the ICollectionView object can provide multi-level sorting, filtering, grouping, and many other features, the DataGrid using the ListCollectionView collection can handle single and multiple sorting.

By default, sorting is enabled on the DataGrid. To control turning sorting on or off, you can use two properties: the CanUserSortColumns property on the DataGrid level and the CanUserSort property on the column level.

The CanUserSortColumns and CanUserSort properties are of type Boolean; they are set to a value of False or True.

To disable sorting at the DataGrid level:

CanUserSortColumns="True"

To disable sorting at the column level:

Binding="{Binding Path=LastName}"

Width="100" CanUserSort="False"

Header="Last Name">

The above is the built-in simple sorting feature that ships within the Silverlight 2.0 DataGrid. Take a look at the following two articles to learn how to implement custom sorting:

         "Silverlight DataGrid Custom Sorting" (http://weblogs.asp.net/manishdalal/archive/2008/12/30/silverlight-datagrid-custom-sorting.aspx)

         "Custom Sort Icons with Silverlight 2's DataGrid Control" (http://mattberseth.com/blog/2008/08/custom_sort_icons_with_silverl.html)

You'll find a working example of the code presented in this article at http://bhaidar.net/SilverlightDataGrid/DataGridPaging.aspx.

Final Installment

This article is the last in a series on the Silverlight 2.0 DataGrid that has spread over the past few months. The series focused on exploring the different features that the DataGrid constitutes in a simple and direct manner without going into custom solutions and workarounds.

This final installment focuses on implementing a simple navigation UI that can be used to page through the DataGrid pages, one at a time. In addition, I demonstrated the built-in sorting feature of the DataGrid, showing how simple it is to enable or disable sorting in a DataGrid by controlling only two properties.

Bilal Haidar ([email protected]) is a Microsoft MVP in ASP/ASP.NET. He is an MCP, MCTS, MCPD, MCT, and Telerik MVP. He is a lead software developer at CCC, a multinational construction company based in Athens, Greece.

Source code accompanying this article is available on this site for download.

Figure 2: Simple DataGrid with three columns

IsReadOnly="True"

x:Name="dgEmployees"

AutoGenerateColumns="False"

HeadersVisibility="Column"

RowBackground="Beige"

AlternatingRowBackground="AliceBlue"

SelectionMode="Single"

GridLinesVisibility="Horizontal"

ColumnWidth="SizeToHeader"

ItemsSource="{Binding}" >

Binding="{Binding Path=FirstName}"

CanUserReorder="False"

CanUserSort="False"

Width="100"

Header="First Name">

Binding="{Binding Path=LastName}"

Width="100"

Header="Last Name">

Binding="{Binding Path=IsMarried}"

Header="Is Married?"

IsThreeState="True" />

Figure 3: XAML navigation UI

CornerRadius="3" Padding="5" Margin="2">

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish