Click here to Skip to main content
15,887,214 members
Articles / Web Development / ASP.NET
Article

Custom editable Datagrid with paging and sorting

Rate me:
Please Sign up or sign in to vote.
3.55/5 (19 votes)
3 Dec 20031 min read 229.9K   3.6K   73   25
How to create a grid control for easy editing

Introduction

This article shows you how to create a custom DataGrid with paging, alternate sorting, and is also completely editable

Details

When I was developing some asp.net pages, I lost a lot of time with Datagrids. The code here is to made that work more simple. Only drag the control to the page, complete some properties, point to the methods that controls the updating, deleting and you have a complete editable grid.

C#
[ToolboxData("<{0}:editableElphGrid runat="\""server\">
    </{0}:editableElphGrid>")]
//ParseChildren allow to work with templates inside the custom datagrid
[ParseChildren(true)]
public class editableElphGrid : System.Web.UI.WebControls.DataGrid
{
    /// <summary>
    /// Points to the method that returns a datatable with data
    /// Apunta a la funcion q devolvera un dataTable con los datos
    /// </summary>
    public delegate DataTable getData();
    /// <summary>
    /// Obtain data event 
    /// Evento de obtener datos
    /// </summary>
    public event getData GetData;
    /// <summary>
    /// Points to method(to update data)
    /// Apunta a un metodo q nos servira para modificar datos
    /// </summary>
    public delegate void updateData(int dataKey,DataGridCommandEventArgs e);
    /// <summary>
    /// Update data event
    /// </summary>
    public event updateData UpdateData;
    /// <summary>
    /// Points to method(delete data)
    /// Apunta al metodo q usaremos para eliminar los datos
    /// </summary>
    public delegate void deleteData(int dataKey,DataGridCommandEventArgs e);
    /// <summary>
    /// delete data event
    /// </summary>
    public event deleteData DeleteData; 
    /// <summary>
    /// Cancel data
    /// </summary>
    public delegate void cancelData(int dataKey,DataGridCommandEventArgs e);
    /// <summary>
    /// cancel data event
    /// </summary>
    public event cancelData CancelData;
    /// <summary>
    /// edit data
    /// </summary>
    public delegate void editData(int dataKey,DataGridCommandEventArgs e);
    /// <summary>
    /// edit data event
    /// </summary>
    public event editData EditData;
    // Note: the params passed on the delegates
    // dataKey: is the DataKey field of the edited/
    // canceled/updated/deleted row
    // e: for work with the cells of the grid
    /// <summary>
    /// First sorting field
    /// campo por el q se ordenara en la primera carga
    /// </summary>
    private string _cFirst="";
    /// <summary>
    /// First sorting field
    /// campo por el q se ordenara en la primera carga
    /// </summary>
    public string FirstSortingField
    {
        get
        {return _cFirst;}
        set
        {_cFirst=value;}
    }
    // Inicializamos el grid
    protected override void OnInit(EventArgs e)
    {
        //paginacion=true
        this.AllowPaging=true;
        //ordenacion=true
        this.AllowSorting=true;
        //evento cambio de pagina
        //ADD the events
        this.PageIndexChanged+=new DataGridPageChangedEventHandler(
              cPage_elphGrid);
        //evento ordenar
        this.SortCommand+=new DataGridSortCommandEventHandler(
               Order_elphGrid);
        //evento de cargar datos
        this.Load+=new EventHandler(elphGrid_Load);
        this.EditCommand+=new DataGridCommandEventHandler(Edit_elphGrid);
        this.CancelCommand+=new DataGridCommandEventHandler(Cancel_elphGrid);
        this.DeleteCommand+=new DataGridCommandEventHandler(Delete_elphGrid);
        this.UpdateCommand+=new DataGridCommandEventHandler(Update_elphGrid);
        //clear the columns
        //limpiamos las columnas
        this.Columns.Clear();
        //create the editComandColumn an deleteColumn
        //creamos las columnas de editar i eliminar
        EditCommandColumn col=new EditCommandColumn();
        col.ButtonType=ButtonColumnType.LinkButton;
        col.CancelText="Cancel";
        col.EditText="Edit";
        col.UpdateText="Update";
        this.Columns.Add(col);
        ButtonColumn delCol=new ButtonColumn();
        delCol.CommandName="Delete";
        delCol.ButtonType=ButtonColumnType.LinkButton;
        delCol.Text="Delete";
        this.Columns.Add(delCol);
    }
    private void elphGrid_Load(object sender, EventArgs e)
    {
        if(!this.Page.IsPostBack)
        {
            //changed Session object for Viewstate
            if(this.AllowSorting&&this._cFirst!="")
                this.ViewState.Add("_orderBy",this._cFirst);
            this.ViewState.Add("_orderType","ASC");
            this.DataSource = CreateDataSet();
            this.DataBind();
        }
    }
    private void cPage_elphGrid(object sender, 
             DataGridPageChangedEventArgs e)
    {
        //PAging
        this.CurrentPageIndex = e.NewPageIndex;
        this.DataSource = CreateDataSet();
        this.DataBind();
    }
    private ICollection CreateDataSet() 
    {
        //this.ObtenerDatos call a external function that return data
        DataTable dt=this.GetData();
        if(this.AllowSorting&&this.ViewState["_orderBy"]!=null)
        {
            //sort the grid
            if(this.ViewState["_orderType"].ToString() == "ASC")
                dt.DefaultView.Sort=(string)
                   this.ViewState["_orderBy"].ToString()+" ASC";
            else if(this.ViewState["_orderType"].ToString()=="DESC")
                dt.DefaultView.Sort=(string)this.ViewState["_orderBy"]+
                          " DESC";
        }
        return dt.DefaultView;
    }
    public void Order_elphGrid(object sender, DataGridSortCommandEventArgs e) 
    { 
        this.ViewState["_orderBy"]=(string)e.SortExpression;
        if(this.ViewState["_orderType"].ToString()=="ASC")
            this.ViewState["_orderType"]="DESC";
        else if(this.ViewState["_orderType"].ToString()=="DESC")
            this.ViewState["_orderType"]="ASC";
        this.DataSource = CreateDataSet();
        this.DataBind(); 
    }
    public void Edit_elphGrid(object sender, 
           System.Web.UI.WebControls.DataGridCommandEventArgs e)
    {
        int id=Convert.ToInt32(this.DataKeys[e.Item.ItemIndex]);
        this.EditData(id,e);
        this.EditItemIndex=e.Item.ItemIndex;
        this.DataSource = CreateDataSet();
        this.DataBind();
    }
    public void Delete_elphGrid(object sender, 
          System.Web.UI.WebControls.DataGridCommandEventArgs e)
    {
        int id=Convert.ToInt32(this.DataKeys[e.Item.ItemIndex]);
        this.DeleteData(id,e);
        this.EditItemIndex=-1;
        this.DataSource = CreateDataSet();
        this.DataBind();
    }
    public void Update_elphGrid(object sender, 
           System.Web.UI.WebControls.DataGridCommandEventArgs e) 
    {
        int id=Convert.ToInt32(this.DataKeys[e.Item.ItemIndex]);
        this.UpdateData(id,e);
        this.EditItemIndex=-1;
        this.DataSource = CreateDataSet();
        this.DataBind();
    }
    public void Cancel_elphGrid(object sender, 
            System.Web.UI.WebControls.DataGridCommandEventArgs e) 
    {
        int id=Convert.ToInt32(this.DataKeys[e.Item.ItemIndex]);
        this.CancelData(id,e);
        this.EditItemIndex=-1;
        this.DataSource = CreateDataSet();
        this.DataBind();
    }
}

Well, now add the control on a page, and then you must fill the fields .

DataKeyField: That is the key field of the table, the unique identifier of a row. I put because I use that on Database actions, like delete a specific row etc.

And on the tab of Events :- GetData, CancelData, EditData and DeleteData.

Finally you should have something like this.

On the aspx page:

HTML
<cc1:editableElphGrid id="EditableElphGrid1" runat="server" 
    DataKeyField="intId"></cc1:editableElphGrid>

On the code behind

C#
protected elphControls.editableElphGrid EditableElphGrid1;
   
private void InitializeComponent()
{    
 this.EditableElphGrid1.DeleteData += 
   new elphControls.editableElphGrid.eliminarDatos(this.del);
 this.EditableElphGrid1.GetData += 
   new elphControls.editableElphGrid.obtenerDatos(this.obt);
this.EditableElphGrid1.EditData += 
   new elphControls.editableElphGrid.editarDatos(this.edit);
 this.EditableElphGrid1.UpdateData += 
   new elphControls.editableElphGrid.actualizarDatos(this.act);
 this.EditableElphGrid1.CancelData += 
   new elphControls.editableElphGrid.cancelarDatos(this.cncl);
 this.Load += new System.EventHandler(this.Page_Load);
}
private System.Data.DataTable obt()
{
OleDbConnection conn=new OleDbConnection(
    "Provider=Microsoft.Jet.OLEDB.4.0;Data source=E:\\bdProves.mdb");
 OleDbDataAdapter adapter=new OleDbDataAdapter("select * from tabla",conn);
 adapter.SelectCommand.CommandType=CommandType.Text;
 conn.Open();
 DataSet ds=new DataSet();
 adapter.Fill(ds,"aa");
 conn.Close();
 conn.Dispose();
 return ds.Tables["aa"];
}
private void edit(int dataKey, 
    System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
//here the logic asociated with edit comand... if you have
}
private void del(int dataKey, 
    System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
 //here the logic asociated with delete comand
}
private void cncl(int dataKey, 
    System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
 //here the logic asociated with Cancel comand
}
private void act(int dataKey, 
    System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
 //here the logic asociated with update comand
}

Update

Changed the session to save the sorting params for a viewstate, now you can have two grids on the same page. Also Changed the declaration of the first sorting field, now this isn't necessary. Thanks to Zanoza.

Conclusion

I think that this grid is a good base to customize a datagrid. Hope it could be useful. All comments about this are welcomed.

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



Comments and Discussions

 
Questionevents firing twice Pin
mojkurs9-Feb-06 15:39
mojkurs9-Feb-06 15:39 
AnswerRe: events firing twice Pin
mojkurs9-Feb-06 16:54
mojkurs9-Feb-06 16:54 
GeneralGetting text from edit/update Pin
bkerr1-Nov-05 19:25
bkerr1-Nov-05 19:25 
GeneralDataGrid : column width Pin
thanchu2-Oct-05 18:22
thanchu2-Oct-05 18:22 
GeneralProgramming Style Tips Pin
Pinhead_Me18-Oct-04 9:36
Pinhead_Me18-Oct-04 9:36 
GeneralRe: Programming Style Tips Pin
Klom Dark23-Jan-06 4:43
Klom Dark23-Jan-06 4:43 
GeneralRe: Programming Style Tips Pin
Pinhead_Me23-Jan-06 7:39
Pinhead_Me23-Jan-06 7:39 
GeneralRe: Programming Style Tips Pin
mtone28-Jan-07 4:32
mtone28-Jan-07 4:32 
Generallogic asociated with update comand Pin
Hamish Ahern18-Oct-04 1:31
Hamish Ahern18-Oct-04 1:31 
QuestionCan you write VB.NET? Pin
Hamish Ahern18-Oct-04 0:40
Hamish Ahern18-Oct-04 0:40 
GeneralHola Pin
Fernando Finelli21-Jul-04 7:04
Fernando Finelli21-Jul-04 7:04 
GeneralControl LoadViewState Pin
Rruedi3-Jul-04 6:11
Rruedi3-Jul-04 6:11 
General@ Register Pin
fsdkjfskl17-Mar-04 4:02
fsdkjfskl17-Mar-04 4:02 
QuestionHow to use the source file? Pin
deny0123-Jan-04 3:46
deny0123-Jan-04 3:46 
QuestionHow do I had non autogenerate columns ? Pin
Ernest Bariq25-Dec-03 22:20
Ernest Bariq25-Dec-03 22:20 
AnswerRe: How do I had non autogenerate columns ? Pin
Ernest Bariq30-Dec-03 5:51
Ernest Bariq30-Dec-03 5:51 
GeneralError Pin
GeorgeMar10-Dec-03 5:31
GeorgeMar10-Dec-03 5:31 
Can someone help me?
I'm getting the following error when I click the edit or delete button:

Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index]
System.Collections.ArrayList.get_Item(Int32 index) +91
System.Web.UI.WebControls.DataKeyCollection.get_Item(Int32 index)
elphControls.editableElphGrid.Edit_elphGrid(Object sender, DataGridCommandEventArgs e)
System.Web.UI.WebControls.DataGrid.OnEditCommand(DataGridCommandEventArgs e)
System.Web.UI.WebControls.DataGrid.OnBubbleEvent(Object source, EventArgs e)
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
System.Web.UI.WebControls.DataGridItem.OnBubbleEvent(Object source, EventArgs e)
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e)
System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
System.Web.UI.Page.ProcessRequestMain()


I'm using the following VB.NET code

Imports System.Data
Imports System.Data.SqlClient
Public Class editgrid
Inherits System.Web.UI.UserControl

#Region " Web Form Designer Generated Code "

Protected WithEvents EditableElphGrid1 As elphControls.editableElphGrid

'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub

#End Region

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
End Sub

Private Sub InitializeComponent()

AddHandler EditableElphGrid1.DeleteData, AddressOf Me.del
AddHandler EditableElphGrid1.GetData, AddressOf Me.obt
AddHandler EditableElphGrid1.EditData, AddressOf Me.edit
AddHandler EditableElphGrid1.UpdateData, AddressOf Me.act
AddHandler EditableElphGrid1.CancelData, AddressOf Me.cncl

End Sub
Private Function obt() As System.Data.DataTable
Dim conn As New SqlConnection("server=NORADWEB_SQL;database=OnLineBookingDB;uid=olbUser;pwd=olbUser;")
Dim adapter As New SqlDataAdapter("select top 500 * from olbOrderTest", conn)
adapter.SelectCommand.CommandType = CommandType.Text
conn.Open()
Dim ds As DataSet = New DataSet
adapter.Fill(ds, "aa")
conn.Close()
conn.Dispose()
Return ds.Tables("aa")
End Function
Private Sub edit(ByVal dataKey As Integer, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
'here the logic asociated with edit comand... if you have
End Sub
Private Sub del(ByVal dataKey As Integer, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
'here the logic asociated with delete comand
End Sub
Private Sub cncl(ByVal dataKey As Integer, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
'here the logic asociated with Cancel comand
End Sub
Private Sub act(ByVal dataKey As Integer, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
'here the logic asociated with update comand
End Sub

End Class

GeneralRe: Error Pin
Elph10-Dec-03 10:33
Elph10-Dec-03 10:33 
GeneralRe: Error Pin
GeorgeMar10-Dec-03 23:14
GeorgeMar10-Dec-03 23:14 
GeneralRe: Error Pin
Anonymous11-Dec-03 1:26
Anonymous11-Dec-03 1:26 
GeneralRe: Error Pin
GeorgeMar11-Dec-03 3:05
GeorgeMar11-Dec-03 3:05 
GeneralProblem with first loading Pin
Zanoza5-Dec-03 4:27
Zanoza5-Dec-03 4:27 
GeneralRe: Problem with first loading Pin
Elph5-Dec-03 7:56
Elph5-Dec-03 7:56 
GeneralThow! Spanish! Pin
Jonathan de Halleux4-Dec-03 20:15
Jonathan de Halleux4-Dec-03 20:15 
GeneralRe: Thow! Spanish! Pin
Elph4-Dec-03 20:33
Elph4-Dec-03 20:33 

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

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