Introduction
Pagination (DataPager) is a built-in control in Silverlight 3.0. I have
extended its behavior and implemented functionality for “Displaying X – Y
of Z Records”.
I have published article at http://saffroze.com/advanced-datapager-with-displaying-record-number-in-silverlight/
Background
Here are some background definition of DataPager elements
- DataPager
The DataPager class is used to page data and to display navigation controls for data-bound controls and displaying text like “Displaying records 1-5 of 12”.
<Control:DataPagerPlus Name="pagerEmployees" Grid.Row="1" PageSize="5" VerticalAlignment="Top" HorizontalAlignment="Stretch" />
- PagedCollectionView
Represents a view for grouping, sorting, filtering, and navigating a paged data collection PagedCollectionView employees = new PagedCollectionView(Employees.Load());
- ResourceDictionary
A resource dictionary is a keyed dictionary of objects that can be used both in XAML and in code. XAML is the most common usage, particularly for initially defining the object resources in a resource dictionary.
I have modified default style of DataPage and added TextBlock for displaying records number. I have used Expression Blend to modify DataPager style. It is very complex and lengthy to edit manually. These are few lines I have made changes in style.<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SampleDataPager.App"
xmlns:test="clr-namespace:AdvancedDataPager;assembly=AdvancedDataPager"
xmlns:Control="clr-namespace:AdvancedDataPager;assembly=AdvancedDataPager">
<Application.Resources>
<ResourceDictionary>
.
.
<TextBlock x:Name="txtPage" Grid.Column="10" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5,0,5,0" Text="{Binding DisplayRecordsText, RelativeSource={RelativeSource TemplatedParent}}"/>
.
.
</ResourceDictionary>
</Application.Resources>
</Application>
- Employee
To test pagination in this post I created a class of type “Employee” to store Employee ID, Name, Department and Salary for each contact with sample data public class Employee
{
public int EmployeeID { get; set; }
public string Name { get; set; }
public string Department { get; set; }
public double Salary { get; set; }
}
- DataGrid
Displays data in a customizable grid.
<sdk:DataGrid Name="grdEmployees" Grid.Row="0" AutoGenerateColumns="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
Implementation
- Add reference of AdvancedDataPager.dll from following location
..\AdvancedDataPager\AdvancedDataPager\Bin\Debug. - Drag DataPagerPlus from your toolbox to Page.xaml as per following.
- Add following code in MainPage.xaml
<UserControl x:Class="SampleDataPager.MainPage"
xmlns:Control="clr-namespace:AdvancedDataPager;assembly=AdvancedDataPager"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="500">
<Grid x:Name="LayoutRoot" Background="White" Width="500" Height="400">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<sdk:DataGrid Name="grdEmployees" Grid.Row="0" AutoGenerateColumns="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
<Control:DataPagerPlus Name="pagerEmployees" Grid.Row="1" PageSize="5" VerticalAlignment="Top" HorizontalAlignment="Stretch" />
</Grid>
</UserControl>
- Add following code in MainPage.xaml.cs for binding data to DataGrid and assign it’s ItemSource to DataPagerPlus.
PagedCollectionView employees = new PagedCollectionView(Employees.Load());
grdEmployees.ItemsSource = employees;
pagerEmployees.Source = grdEmployees.ItemsSource;
Employees.Load() function will return list of employees
public class Employees : ObservableCollection<Employee>
{
public static ObservableCollection<Employee> Load()
{
ObservableCollection<Employee> objColEmp = new ObservableCollection<Employee>();
objColEmp.Add(new Employee { EmployeeID = 1001, Name = "Imdadhusen Sunasara", Department = ".Net", Salary = 15000 });
objColEmp.Add(new Employee { EmployeeID = 1002, Name = "Manoj Savalia", Department = ".Net", Salary = 11000 });
objColEmp.Add(new Employee { EmployeeID = 1003, Name = "Ravi Patel", Department = "Java", Salary = 9000 });
objColEmp.Add(new Employee { EmployeeID = 1004, Name = "Vasim Saiyad", Department = "Java", Salary = 8000 });
objColEmp.Add(new Employee { EmployeeID = 1005, Name = "Jaypal Chawda", Department = "QA", Salary = 11000 });
objColEmp.Add(new Employee { EmployeeID = 1006, Name = "Ashish Rawal", Department = ".Net", Salary = 1000 });
objColEmp.Add(new Employee { EmployeeID = 1007, Name = "Hasan Sunasara", Department = "Java", Salary = 18000 });
objColEmp.Add(new Employee { EmployeeID = 1008, Name = "Ambicaprasad Maurya", Department = ".Net", Salary = 12000 });
objColEmp.Add(new Employee { EmployeeID = 1009, Name = "Sagar Rawal", Department = "Flex", Salary = 7000 });
objColEmp.Add(new Employee { EmployeeID = 1010, Name = "Harsh Contractor", Department = ".Net", Salary = 8000 });
objColEmp.Add(new Employee { EmployeeID = 1011, Name = "Jigar Pandya", Department = "Android", Salary = 12000 });
objColEmp.Add(new Employee { EmployeeID = 1012, Name = "Rakesh Jogani", Department = "Flex", Salary = 7000 });
return objColEmp;
}
}
- Modify Application.Resources in App.xaml for displaying Record Number
<Application.Resources>
<ResourceDictionary>
<Style TargetType="Control:DataPagerPlus" >
.
.
.
.
<TextBlock Grid.Column="10" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5,0,5,0" Text="{Binding DisplayRecordsText, RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Application.Resources>
Component Logic
-
Extending DataPager
public class DataPagerPlus : DataPager
- Create Dependency Property for displaying record number. (As per MSDN
“dependency properties is to provide a way to compute the value of a
property based on the value of other inputs. These other inputs might
include system properties such as themes and user preference,
just-in-time property determination mechanisms such as data binding and
animations/storyboards, multiple-use templates such as resources and
styles, or values known through parent-child relationships with other
elements in the element tree. In addition, a dependency property can be
implemented to provide self-contained validation, default values,
callbacks that monitor changes to other properties, and a system that
can coerce property values based on potentially runtime information “
- Register PageIndexChanged events on control load event to update displaying page number text.
this.PageIndexChanged += new EventHandler(CustomPager_PageIndexChanged);
- call function for displaying text on DataPagerPlus when page index is changed.
private void CustomPager_PageIndexChanged(object sender, EventArgs e)
{
SetDisplayRecordsText(sender);
}
- Actual code for displaying text.
private void SetDisplayRecordsText(object sender)
{
int RecordCount = (base.ItemCount == 0) ? ((PagedCollectionView)((DataPager)(sender)).Source).ItemCount : base.ItemCount;
int PageSize = base.PageSize;
int PageIndex = (base.PageIndex + 1);
int currentEndRow = (PageIndex * PageSize);
if (currentEndRow > RecordCount) currentEndRow = RecordCount;
if (currentEndRow < PageSize) PageSize = currentEndRow;
int currentStartRow = (RecordCount > 0) ? (currentEndRow - PageSize) + 1 : 0;
int TotalRecordsOnPage = (PageIndex * PageSize) - RecordCount;
currentStartRow = (TotalRecordsOnPage == 1) ? currentEndRow : ((PageIndex - 1) * PageSize) + 1;
this.DisplayRecordsText = string.Format("Displaying record(s) {0:0}-{1:0} of {2:0}", currentStartRow, currentEndRow, RecordCount);
}
Your Thoughts
If you find some issues or bugs with it, just leave a comment or drop me
an email. If you make any notes on this, let me know that too so I
don't have to redo any of your hard work. Please provide a "Vote" if this would be helpful.