- Creating the Sample Project
- Replacing the Built-In Data Grid with Custom Controls
- Implementing the Custom Paging Mechanism
- Fine-Tuning the Layout
- Testing the Application
- Conclusion
Implementing the Custom Paging Mechanism
To reproduce the paging mechanism, you need some buttons and some label/text boxes. Usually labels and text boxes are added to screens automatically to display or edit data, but you have a chance to add controls that are not data-bound to the original collection and that you can use for your own purposes. To accomplish this goal, you use the so-called "local properties."
- With the screen designer open, click Add Data Item. In the Add Data Item dialog, select the Local Property option. Make sure that the Is Required checkbox is unselected (see Figure 7).
- The new property is called CurrentPage, and it represents the current page in the data collection. We'll use this property to write a different page number for moving easily to another page.
- The CurrentPage property is visible on the left side of the designer. Drag it onto the designer surface and release it under the Columns Layout you created earlier (see Figure 8).
- Create a local property called PageNumber, of type String, not required. Drag the new property onto the screen designer, but change its appearance to make it a label instead of a text box (see Figure 9). This property will contain the number of total pages. Both properties will be populated in code.
Now it's time to add some buttons to control the navigation between pages. In particular, you need four buttons to let the user move to the first page, the last page, the next page, and the previous page.
- Expand the Command Bar element located under the Custom Control. Here you'll find three built-in buttons that perform data operations over the bound collection (see Figure 10).
- Start by adding a new button. You must specify a name for a method that will be associated to the button, as shown in Figure 11. For each button you'll handle later, you need both the Execute and CanExecute method hooks.
- Associate the methods FirstPage, LastPage, NextPage, and PreviousPage to their related buttons. You can also change each button's appearance from the classic layout to the hyperlink layout (refer to Figure 10).
- Click Write Code in the screen designer.
The rest of the work must be done inside the code editor. At startup, the application must get a reference to the text box that shows the current page number and that allows changing the page (other than setting up initial values). This functionality requires interacting with the Silverlight infrastructure and is performed by the code shown in Listing 2, which is commented for easier reading.
Listing 2Handling the changing of pages.
'Hold a reference to the text box where page number can be changed Private changePageBox As Windows.Controls.TextBox Private Sub EditableCustomersGrid_Created() 'Return the specified control in a LightSwitch fashion Dim pageBox = Me.FindControl("CurrentPage") 'Subscribe to the ControlAvailable event and get 'the real control via the e.Control property AddHandler pageBox.ControlAvailable, Sub(sender As Object, e As ControlAvailableEventArgs) Me.changePageBox = CType(e.Control, Windows.Controls.TextBox) 'When the user press Enter, retrieve the page number (if valid) 'and change the current page AddHandler Me.changePageBox.KeyUp, Sub(senderK As Object, eK As Windows.Input.KeyEventArgs) If eK.Key = Windows.Input.Key.Enter Then Dim pageNumber As Integer If Integer.TryParse(Me.changePageBox.Text, pageNumber) Then Me.Customers.Details.PageNumber = pageNumber Me.PageNumber = " of " + CStr(Me.Customers.Details.PageCount) Me.CurrentPage = CStr(pageNumber) End If End If End Sub End Sub 'Set values at startup Me.CurrentPage = "1" Me.PageNumber = " of " + CStr(Me.Customers.Details.PageCount) End Sub
Everything goes around the Details property of a collection, which also exposes the PageCount and PageNumber properties. These properties allow obtaining the number of total pages for the collection and setting the current page. Notice that the PageNumber label is populated with an informational message showing the total number of pages.
Now let's move on to writing code for the FirstPage and LastPage methods. These methods are the simplest of the set, since you only need to set the page number and update the displayed text. Listing 3 shows the code for this task:
Listing 3Implementing navigation to the first page and the last page.
Private Sub FirstPage_Execute() Me.Customers.Details.PageNumber = 1 Me.CurrentPage = CStr(Me.Customers.Details.PageNumber) Me.PageNumber = " of " + CStr(Me.Customers.Details.PageCount) End Sub Private Sub LastPage_Execute() Me.Customers.Details.PageNumber = Me.Customers.Details.PageCount Me.CurrentPage = CStr(Me.Customers.Details.PageNumber) Me.PageNumber = " of " + CStr(Me.Customers.Details.PageCount) End Sub
It's easy to move to the first and last page by setting the Details.PageNumber property of the collection. You don't need to handle CanExecute for these buttons, since a collection always has a first page and a last page.
Things are a little bit different for the NextPage and PreviousPage methods, whose code is shown in Listing 4.
Listing 4Implementing navigation to the next page and the previous page.
Private Sub NextPage_Execute() Me.Customers.Details.PageNumber += 1 Me.CurrentPage = CStr(Me.Customers.Details.PageNumber) Me.PageNumber = " of " + CStr(Me.Customers.Details.PageCount) End Sub Private Sub NextPage_CanExecute(ByRef result As Boolean) result = (Me.Customers.Details.PageNumber < Me.Customers.Details.PageCount) End Sub Private Sub PreviousPage_Execute() Me.Customers.Details.PageNumber -= 1 Me.CurrentPage = CStr(Me.Customers.Details.PageNumber) Me.PageNumber = " of " + CStr(Me.Customers.Details.PageCount) End Sub Private Sub PreviousPage_CanExecute(ByRef result As Boolean) result = Me.Customers.Details.PageNumber > 1 End Sub
As you can see, it's still easy to move to the next or previous page, simply by increasing or decreasing the page number. However, you need to ensure that the action is possible by handling CanExecute and calculating the current position. If the result of the evaluation is False, the button will be disabled automatically until the result becomes True.