Click here to Skip to main content
Click here to Skip to main content

DataGridNavigator

, 17 Apr 2004
Rate this:
Please Sign up or sign in to vote.
ASP.NET server control which renders DataGrid navigator.

Introduction

One of my most used ASP.NET control is DataGrid. Presenting data from tables is very easy and nice with only one exception - the page navigator. Showing only page numbers or only two links (to previous and next page) is insufficient for me, and completely inexplicable for my clients. So I decided to create DataGridNavigator Server Control, the main task of which is to generate the page navigator for DataGrid object. The navigator can have the following buttons:

  • to jump to the first / last page (text or image)
  • to jump to the previous / next page (text or image)
  • to jump to the page no. ... (text only Smile | :) )

The navigator control is rendered independently of the DataGrid control, and you can bind multiple navigators to one DataGrid.

The control, properties and editors

The control inherits from the WebControl class (in ASP.NET, the control can inherit directly or indirectly from either the Control or WebControl base class) and is rendered in the span HTML tag.

Some of the properties have been assigned specified editors, like System.Web.UI.Design.ImageUrlEditor (for the xxxButtonImageUrl properties). This editor shows "Select image" dialog window (the same which is used in the ImageUrl property of the HyperLink control). All we have to do is to set the property's EditorAttribute:

[Category("Buttons"), 
 DefaultValue(""), 
 Description("First button's image URL."), 
 EditorAttribute(typeof(System.Web.UI.Design.ImageUrlEditor), 
 typeof(System.Drawing.Design.UITypeEditor))] 
public string FirstButtonImageUrl 
{
   get { object o = ViewState["FirstButtonImageUrl"]; 
         return (o==null) ? String.Empty : (string) o; }
   set { ViewState["FirstButtonImageUrl"] = value.Trim(); } 
} 

There's also a special editor for the DataGridName property, which shows a list of all DataGrid objects on the page. You can find the editor's implementation in the DataGridNavigatorEditor.cs file.

The SelectDataGrid editor class

All editor classes should derive from the UITypeEditor class. One of the methods you should implement is the GetEditStyle, which returns editor type:

  • DropDown - dropdown dialog
  • Modal - modal window
  • None - no UI.

For example:

public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
    return UITypeEditorEditStyle.DropDown;
}

The next method to implement is EditValue, in which the editor window/control is created. In the case of the dropdown editor, we can use the ListBox control. As you can see in the DataGridNavigatorEditor.cs file, I've created an abstract class ObjectListEditor which implements the base functionality for that kind of editors. The class has InsertItems method used to fill the list with items. The main editor is implemented in the SelectDataGrid class, which derives from the ObjectListEditor class. Here is the implementation of the InsertItems method:

protected override void InsertItems(ListBox.ObjectCollection items, 
                                            ComponentCollection components)
{
   // iterate thru all page's components
   for (int i = 0; i < components.Count; i++)
      // check if component is the DataGrid.
      if (components[i] is System.Web.UI.WebControls.DataGrid)
         items.Add(((System.Web.UI.WebControls.DataGrid)components[i]).ID);
}

As you can see, there is an iteration loop through the page's components. Every DataGrid component is added into the list items collection. If, for some reason, you would like to add other components, just change the conditional test.

Page's components collection (the method's component argument) is provided by the ITypeDescriptorContext interface (precisely by the Container.Components property), as you can see in the EditValue method implementation (in the ObjectListEditor class).

To assign the editor to the property, just set the EditorAttribute:

[Category("Data"),
 DefaultValue(""),
 Description("DataGrid name to which connect the control."),
 Editor(typeof(mavus74.net.Editors.SelectDataGrid), 
 typeof(System.Drawing.Design.UITypeEditor))]
public string DataGridName
{
   get { object o = ViewState["DataGridName"]; 
         return (o==null) ? String.Empty : (string) o; }
   set { ViewState["DataGridName"] = value.Trim(); }
} 

The PostBack event

The main control's event is Command, based on the CommandEventHandler, which is invoked by the button click.

If control uses PostBack events, it should implement the IPostBackEventHandler interface. The Command event property is implemented as follows:

private static readonly object EventCommand = new object();
 
 
...
 
[Category("Action"),
 Description("OnCommand event")]
public event CommandEventHandler Command
{
   add { Events.AddHandler(EventCommand, value); }
   remove { Events.RemoveHandler(EventCommand, value); }
}

This implementation relies on the C# event property construct. Now, it's time to implement the IPostBackEventHandler.RaisePostBackEvent method. In this method, you have to decide which event was invoked (the eventArgument has the event name):

void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
{
   // check event, and raise OnCommand with appropriate arguments.
   switch (eventArgument)
   {
      case "FIRST": 
         OnCommand(new CommandEventArgs("FIRST", 0));
         return;
      case "PREV": 
         OnCommand(new CommandEventArgs("PREV", 
         (dgData.CurrentPageIndex == 0) ? 0 : dgData.CurrentPageIndex - 1));
         return;
      case "NEXT": 
         OnCommand(new CommandEventArgs("NEXT", 
         (dgData.CurrentPageIndex == dgData.PageCount-1) ? dgData.PageCount-1 : 
         dgData.CurrentPageIndex + 1)); 
         return;
      case "LAST": 
         OnCommand(new CommandEventArgs("LAST", dgData.PageCount - 1));
         return;
   }
 
   if (eventArgument.StartsWith("PAGE_"))
   {
     int i = Convert.ToInt32( eventArgument.Remove(0, 5));
     OnCommand(new CommandEventArgs("PAGE", i));
   }
}

The OnCommand implementation:

protected virtual void OnCommand(CommandEventArgs e)
{
   CommandEventHandler clickHandler = (CommandEventHandler)Events[EventCommand];
   if (clickHandler != null) clickHandler(this, e);
}

And the main point - rendering postback event code. The control renders a group of HTML links with post back event. The code is generated by the Page.GetPostBackClientHyperlink method, which gets two parameters:

  • control - the server control which will process the postback
  • argument - the event's argument, which is passed to the RaisePostBackEvent method.
writer.AddAttribute(HtmlTextWriterAttribute.Href, 
    Page.GetPostBackClientHyperlink(this, "FIRST"));

The GetPostBackClientHyperlink method calls the GetPostBackEventReferece and appends 'javascript: ' text at the beginning.

Using the control

First, you need to bind the control with DataGrid by the DataGridName property. You also need to implement the Command event, for example:

private void DataGridNavigator1_Command(object sender, 
                 System.Web.UI.WebControls.CommandEventArgs e)
{
   // e.CommandArgument has new PageIndex
   dgDane.CurrentPageIndex = (int) e.CommandArgument;
   bindData();
}

You also can set button's text, images and CSS class (ButtonsCssClass property). If you don't specify button's ImageUrl, than text link is rendered. Otherwise, image button is rendered. By setting the ShowPageButtons, you can decide to render page numbers. PageButtonCount property decides how many links to render (value between 3 and 21).

Points of Interest

This control shows how to create a server control with post back events handler, assign the property editor and how to create easy property editor.

TO-DO

  • specialized event handler instead of the CommandEventHandler. This handler can provide 2 properties: the DataGrid control and PageNumber (now it's CommandArgument).
  • DisabledImageUrl - image used when the link is disabled.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Mariusz Wojcik
Web Developer
United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
GeneralDisplay image on datagrid Pinmemberquocbao2-Mar-07 14:23 
GeneralFix When Placed on a WebUserControl. PinmemberAsela Gunawardena6-Jun-06 2:47 
QuestionBug!! PinsussMuffadal18-Oct-05 22:36 
Answer[Message Removed] Pinmemberstonber6-Oct-08 8:34 
GeneralNice ! PinmemberTrance Junkie21-Jun-05 22:05 
Generalunable to make it work PinmemberD.Sridhar19-May-05 11:29 
GeneralDefinitely good Pinmemberpinguit29-Sep-04 21:33 
GeneralJust can't get it to work PinmemberDan Wright28-Sep-04 16:41 
GeneralRe: Just can't get it to work Pinmemberjavierdotnet26-Jan-05 1:59 
Generalhide unused controls PinmemberYannick Smits11-Jun-04 20:17 
GeneralRe: hide unused controls Pinmemberdreamer9211-Jul-06 1:33 
GeneralRe: hide unused controls PinmemberYannick Smits17-Jul-06 16:14 
GeneralYou can use AspNetPager free paging control! PinmemberWebdiyer10-Jun-04 15:43 
GeneralRe: You can use AspNetPager free paging control! PinmemberAshaman24-Feb-05 7:48 
Webdiyer wrote:
currently only chinese simplified version is available
 
That, and the fact that your site unavailable kinda makes the DataGridNavigator that much more impressive. Poke tongue | ;-P
GeneralVery good! Pinmemberanson_dragon10-Jun-04 0:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141223.1 | Last Updated 18 Apr 2004
Article Copyright 2004 by Mariusz Wojcik
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid