This is an answer to Part 4 of the Great Silverlight Competency Test. Scoring below.
The tasks were to demonstrate usage of the DataGrid, DataPager and TreeView. Here is one approach…
I opted to create this in an MVVM structure, but not using an MVVM library. I began by creating a MainPage.xaml with a DataGrid and a DataPager. It is important to drag these from the toolbox and not just enter them directly into the Xaml, because dragging them onto either the design form or the Xaml page causes Visual Studio to add the namespace you need (sdk) pointing to http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk
<sdk:DataGrid Width="Auto" ItemsSource="{Binding}" /> <sdk:DataPager DisplayMode="FirstLastPreviousNextNumeric" Source="{Binding}" PageSize="10" />
The DataGrid’s ItemSource is set to Binding but with no property; this will cause it to bind to the collection presented by the DataContext.
The DataPager has three properties set
- DisplayMode which determines how the paging will be displayed
- Source – set to the same source as the DataGrid’s ItemsSource
- PageSize – how many records per page
The Data
The data we’ll bind to is the same Customer data I’ve used in previous demonstrations, cut down just a bit here. There are two classes: Customer, and also CustomerCollection. The latter exists to generate a random collection of 500 Customer objects and to make that collection available as a property. Both classes are defined in Customer.cs which itself is in the folder Model. Here’s the complete Customer and CustomerCollection source code.
using System; using System.Collections.Generic; using System.Collections.ObjectModel; namespace PagingData.Model { public class CustomerCollection { private readonly ObservableCollection<Customer> _customers = new ObservableCollection<Customer>(); public ObservableCollection<Customer> Customers { get { return _customers; } } public CustomerCollection() { GenerateCustomers(500); } public void GenerateCustomers(int howMany) { var firsts = new List<String> { "Abe", "Alice", "Barry", "Basha", "Charlie", "Colette", "David", "Davida", "Edgar", "Elizabeth", "Frank", "Fran", "George", "Gary", "Harry", "Isaac", "Jesse", "Jessica", "Kevin", "Katrina", "Larry", "Linda", "Mark", "Melinda", "Nick", "Nancy", "Oscar", "Ophilia", "Peter", "Patricia", "Quince", "Quintina", "Robert", "Roberta", "Shy", "Sarah", "Tom", "Teri", "Uberto", "Uma", "Victor", "Victoria", "Walter", "Wendy", "Xerxes", "Xena", "Yaakov", "Yakira", "Zach", "Zahara" }; var lasts = new List<String> { "Anderson", "Baker", "Connors", "Davidson", "Edgecumbe", "Franklin", "Gregory", "Hines", "Isaacson", "Johnson", "Kennedy", "Liberty", "Mann", "Nickerson", "O'Dwyer", "Patterson", "Quimby", "Richardson", "Stevenson", "Tino", "Usher", "Van Dam", "Walker", "Xenason", "Yager", "Zachery" }; var streets = new List<String> { "Ash", "Beech", "Cedar", "Dogwood", "Elm", "Filbert", "Ginkgo", "Hawtorn", "Ironwood", "Juniper", "Katsura", "Lilac", "Magnolia", "Nectarine", "Oak", "Palm", "Quince", "Redwood", "Sassafrass", "Tupelo", "Vibrunum", "Walnut", "Yellowwood", "Zelkova" }; var cities = new List<String> { "Acton", "Boston", "Canton", "Dell", "Everstone", "Flintwood", "Gary", "Houston", "Imperial", "Jackson", "Kalamazoo", "Levinworth", "Macon", "New York", "Oak Hill", "Paducah", "Quinzy", "Rochester", "South Falls", "Terra Haute", "Union", "Victoria", "Waipio", "Xenia", "York", "Zanesville" }; var isp = new List<String> { "ATT", "Verizon", "Hotmail", "Gmail", "Sprintnet", "Yahoo" }; var states = new List<String> { "AL", "AK", "AS", "AR", "CA", "CO", "CT", "DE", "FL", "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VA", "WA", "WI", "WY" }; var random = new Random(); for (var i = 0; i < howMany; i++) { var first = firsts[random.Next(0, firsts.Count)]; var last = lasts[random.Next(0, lasts.Count)]; var streetNumberInt = random.Next(101, 999); var streetNumber = streetNumberInt.ToString(); var zipCode = random.Next(10000, 99999).ToString(); var phone = random.Next(200, 999) + "-555-" + random.Next(2000, 9099); var fax = random.Next(200, 999) + "-555-" + random.Next(2000, 9099); var email = first + "@" + isp[random.Next(0, isp.Count)] + ".com"; _customers.Add( new Customer( first, last, streetNumber + " " + streets[ random.Next( 0, streets.Count - 1) ] + " Street", cities[ random.Next(0, cities.Count - 1) ], states[ random.Next(0, states.Count - 1) ], zipCode, phone, fax, email)); } } } public class Customer { public string First { get; set; } public string Last { get; set; } public string Name { get { return First + " " + Last; } } public string Address { get; set; } public string City { get; set; } public string State { get; set; } public string Zip { get; set; } public string Phone { get; set; } public string Fax { get; set; } public string Email { get; set; } public Customer() { } public Customer( string first, string last, string address, string city, string state, string zip, string phone, string fax, string email) { First = first; Last = last; Address = address; City = city; State = state; Zip = zip; Phone = Phone; Fax = fax; Email = email; } } }
MainViewModel
The VM consists of a single property of type PagedCollectionView (the type expected by the DataPager) and a constructor,
public class MainViewModel : ViewModelBase { private PagedCollectionView dataListview; public PagedCollectionView DataListView { get { return dataListview; } } public MainViewModel() { var customerCollection = new CustomerCollection(); var customers = customerCollection.Customers; var customers2 = customers.OrderBy( c => c.Zip ); dataListview = new PagedCollectionView( customers2 ); } }
The constructor begins by instantiating a CustomerCollection and then using that to extract the Customers ObservableCollection. We then introduce a new variable, customers2, which uses a Linq statement to order the results, and that is presented to the PageCollectionView constructor, and the result is stored in the backing member for the public property.
CAUTION: customers2 is now of type IOrderedEnumerable, not ObservableCollection, and if you need an ObservableCollection you’ll need to convert it to be one. For our purposes (read only) it serves just fine. |
Setting the DataContext
The final link is to set the data context in MainPage.xaml.cs
void MainPage_Loaded(object sender, System.Windows.RoutedEventArgs e) { DataContext = new MainViewModel().DataListView; }
The result is a pageable datagrid of Customers.
One Response to Great Silverlight Competency Test Part 4 (Answer)