Skip to main content
Email Password   helpLost your password?

Introduction

In any application you would like to show list of data in the data grid, list box and to improve the performance of the system, you would like to show the first N number of records in the grid. User can request for next records with the help of Navigation bar. 

This article is to create a custom control called <NavigableGrid /> and use it to show a paged data grid.

Also, please vote if you like anything about this article. It helps developers to contribute more. :)

Background

I'm assuming here that you have enough knowledge about how to create a Silverlight Application and debug as required.

In addition to that, you also need to know a bit about what is generic.xaml.

What is generic.xaml?

Generic.xaml is the file where you can define the resources such as Style, Template, that are shared throughout the application.

(For more information, please refer here.)

generic.xaml defines the default visual template for the controls. The recommended location to save this file is $(projectfile)\themes\.

NavigableGrid Control

It is always a good practice to define the User interface of the Control that we are after and then decide the best approach to achieve from code perspective.

NavigableGrid control UI

Navigable_Grid_1.JPG

As shown above in the diagram, we can divide the control into sub controls.

  1. SearchBar
  2. Navigation Bar - Top
  3. Content Presenter
  4. Navigation Bar - Bottom

Now let's go one by one and create custom controls.

SearchBar Control

Search Bar control contains the Text Box, search button and the advanced search link.

You need to define the default template of this control in generic.xaml and define the corresponding control class.

(Refer generic.xaml)

<!-- Search Bar style--> 
<Style TargetType="local:SearchBar"> 
<Setter Property="Template"> 
 <Setter.Value> 
 <ControlTemplate TargetType="local:SearchBar"> 
 ...
 ...
 </ControlTemplate> 
 </Setter.Value> 
</Setter> 
</Style>      

SearchBar Control Class

[TemplatePart(Name = SearchBar.SearchKeywordControlName, Type = typeof(TextBox))]
[TemplatePart(Name = SearchBar.QuickSearchControlName, Type = typeof(Button))]
[TemplatePart(Name = SearchBar.AdvanceSearchControlName, Type = typeof(HyperlinkButton))]
public class SearchBar : Control 
{
}

TemplatePart - Represents an attribute that is applied to the class definition to identify the types of the named parts that are used for control templating.

Two main points to look at in this class are:

  1. How we are overriding the OnApplyTemplate () method of the base class
  2. Constructor

We've also got two custom event handlers for this class that trigger on quick search and advanced search clicks.

/// <summary>
/// Event handler declaration for the quick search.
/// </summary>
public event EventHandler<QuickSearchEventArgs> OnQuickSearch;
/// <summary>
/// Event handler declaration for the Advance search.
/// </summary>
public event EventHandler OnAdvanceSearch;

Note: QuickSearchEventArgs is an another class defining custom event argument.

Navigation Bar Control

As we did for SearchBar, you will define the Navigation bar but we are expecting different controls within the template.

The signature of this class is as follow:

/// <summary>
/// Provides a Navigation bar feature for any list control such as DataGrid, 
/// ListBox etc. To override 
/// the default control template you must consider providing expected controls.
/// </summary>
[TemplatePart(Name = NavigationBar.PageSummaryName, Type = typeof(TextBlock))]
[TemplatePart(Name = NavigationBar.MoveFirstPageName, Type = typeof(HyperlinkButton))]
[TemplatePart(Name = NavigationBar.MovePreviousPageName, Type = typeof(HyperlinkButton))]
[TemplatePart(Name = NavigationBar.MoveNextPageName, Type = typeof(HyperlinkButton))]
[TemplatePart(Name = NavigationBar.MoveLastPageName, Type = typeof(HyperlinkButton))]
[TemplatePart(Name = NavigationBar.GotoBoxName, Type = typeof(TextBox))]
[TemplatePart(Name = NavigationBar.GotoButtonName, Type = typeof(Button))]
public class NavigationBar : Control
{
}

NavigableGrid Control

Now we are ready with all sub controls that need to be used to create a NavigableGrid control.

NavigableGrid control is not different than what we did for SearchBar or NavigationBar. However, it does use the NavigationBar, and search bar control within the template. In addition to that, the NavigableGrid control is derived from ContentControl Silverlight class and that is because it can host any content within it; such as DataGrid.

[TemplatePart(Name = NavigableGrid.SearchBarName, 
Type = typeof(SearchBar))]
[TemplatePart(Name = NavigableGrid.NavigationBarTopPanelName, 
Type = typeof(NavigationBar))]
[TemplatePart(Name = NavigableGrid.NavigationBarBottomPanelName, 
Type = typeof(NavigationBar))]
public class NavigableGrid : ContentControl
{
}

This class has got the following dependency property that can control the background color, font color, Bar orientation, i.e. show top navigation, bottom or both, or none. You can also control the search feature, advance button and so on.

public static readonly DependencyProperty OpaqueColorProperty = 
DependencyProperty.Register("OpaqueColor", typeof(Brush), typeof(NavigableGrid), null);
public static readonly DependencyProperty NavigationBarBackgroundProperty = 
DependencyProperty.Register("NavigationBarBackground", typeof(Brush), 
typeof(NavigableGrid), null);
public static readonly DependencyProperty NavigationBarForegroundProperty = 
DependencyProperty.Register("NavigationBarForeground", typeof(Brush), 
typeof(NavigableGrid), null);
public static readonly DependencyProperty NavigationBarOrientationProperty = 
DependencyProperty.Register("NavigationBarOrientation", 
				typeof(NavigationBarOrientation), 
typeof(NavigableGrid), new PropertyMetadata(NavigationBarOrientation.Both, 
new PropertyChangedCallback(NavigationBarOrientation_Changed)));
public static readonly DependencyProperty PageSizeProperty = 
DependencyProperty.Register("PageSize", typeof(int), typeof(NavigableGrid), 
new PropertyMetadata(10, new PropertyChangedCallback(PageSize_Changed))
public static readonly DependencyProperty CurrentPageProperty = 
DependencyProperty.Register("CurrentPage", typeof(int), typeof(NavigableGrid), 
new PropertyMetadata(new PropertyChangedCallback(CurrentPage_Changed)));
public static readonly DependencyProperty TotalRecordsProperty = 
DependencyProperty.Register("TotalRecords", typeof(int), typeof(NavigableGrid),
 new PropertyMetadata(new PropertyChangedCallback(TotalRecords_Changed)));
public static readonly DependencyProperty IsSearchEnabledProperty = 
DependencyProperty.Register("IsSearchEnabled", typeof(bool), typeof(NavigableGrid), 
new PropertyMetadata(true, new PropertyChangedCallback(IsSearchEnabled_Changed)));
public static readonly DependencyProperty IsAdvanceSearchEnabledProperty = 
DependencyProperty.Register("IsAdvanceSearchEnabled", typeof(bool), 
typeof(NavigableGrid), new PropertyMetadata(true, new 
PropertyChangedCallback(IsAdvanceSearchEnabled_Changed)));

NOTE: Attached source code is well commented and should you have any query, please ask here.

In addition to the property, you can also attach your event listener to some of the important events that must trigger when something happens such as Move next page, go to this page, click on advanced search and so on...

/// <summary>
/// Event handler for Page size changed.
/// </summary>
public event EventHandler<RecordPerPageChangedEventArgs> OnPageSizeChanged;
/// <summary>
/// Event handler for new page request. This event triggers when a new page requested 
/// through the link or Goto feature.
/// </summary>
public event EventHandler<NavigableGridPageChangedEventArgs> OnPageChanged;
/// <summary>
/// Event handler declaration for the quick search.
/// </summary>
public event EventHandler<QuickSearchEventArgs> OnQuickSearch;
/// <summary>
/// Event handler declaration for the Advance search.
/// </summary>
public event EventHandler OnAdvanceSearch;

How to Use this Control?

Create a new XAML file and add the following line of XAML:

<Grid x:Name="LayoutRoot" Background="White">
<self:NavigableGrid x:Name="EmployeeListPage" 
OnPageChanged="EmployeeList_OnPageChanged" IsAdvanceSearchEnabled="True" 
Orientation="Both" IsSearchEnabled="True" OnQuickSearch="EmployeeListPage_OnQuickSearch" 

OnAdvanceSearch="EmployeeListPage_OnAdvanceSearch">
<self:NavigableGrid.Content>
<data:DataGrid x:Name="EmployeeList" AutoGenerateColumns="True" IsReadOnly="True" 
SelectionMode="Single" Width="700" Height="450" />
</self:NavigableGrid.Content>
</self:NavigableGrid>
</Grid> 

In the code behind, you can initialize this grid as normal:

this.EmployeeListPage.PageSize = 5;
this.EmployeeListPage.TotalRecords = list.Count;
this.EmployeeList.ItemsSource = list; 

NOTE: YOU HAVE TO specify your page size, total number of records to NavigableGrid!

Points of Interest

Through this article, you can learn about:

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralLoser Pin
Dewey
19:53 23 Mar '09  
GeneralRe: Loser Pin
R i c k C o de
20:59 18 May '09  
GeneralGreat article. Where is the codefile? Pin
solutionsville
9:31 3 Mar '09  
GeneralRe: Great article. Where is the codefile? Pin
R i c k C o de
21:11 7 May '09  
GeneralWhat am I missing? Pin
Jerry Evans
15:50 24 Nov '08  
GeneralGood work - but no sample code. Pin
jr_pram
18:01 16 Nov '08  
GeneralRe: Good work - but no sample code. Pin
R i c k C o de
4:11 14 May '09  


Last Updated 14 May 2009 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009