Introduction
This article is very useful to all the users who are
working with ASP.Net 2.0 GridView control. Here I am explaining how to work with
GridView control in ASP.Net 2.0 which is very easier then DataGrid Control in
ASP.Net 1.1. I will also explain what are the differences in GridView and
Datagrid Control in ASP.Net 1.1. I want to explain how to work with template
column having datagrid inside.
Background
The basic idea behind this article is to workout with
ASP.Net 2.0's GridView Control than the DataGrid Control in ASP.Net 1.1. As I
had worked with DataGrid Control so I knew how difficult to work with it in same
project. I had done almost same project in ASP.Net 1.1 also. But to work with
ASP.Net 2.0 GridView control is too good, easy and very user friendly. Though I
had faced lot of difficulties in this but still I can say it is far better then
ASP.Net 1.1's grid control for some functionality. GridView control gives you
Edit, Update, Delete, Sorting, Selection and Paging facility built in.
Using the code
Here in this project, I have used ObjectDataSource
control for binding the GridView to the data. This is one of the best features
available in VS.Net 2005. It is very easy to work with it.
The main difference between DataGrid and GridView
control is that the first one has central event handling which means any event
raised by control inside the DataGrid's template column will be handled by
ItemCommand event of datagrid. But this functionality is some what different in
GridView Control. It directly calls the handler of the control.
I mean to say that in GridView Control if you have
added one template column having GridView inside it and now if you select
"Column Sorting" command then it will not call any event of Master grid. It will
directly call the sorting handler of the child grid. It is up to the user to
take advantage of this feature.
So let me explain the code now. Here I have one
MasterTable which is bind to the Master Grid using MasterDataSouce and one
ChildTable which is bind to Gridview inside template column of Mastergird. To
bind the Child Grid to ChildDataSource we have to use RowDataBound event which
is called every time when each row from database is bind to the Grid View's row.
Here, basic idea behind caching is that when cell value
is required you should get it and show it. So what happen behind the screen is:
RowDataBound event of Mastergrid
Protected Sub
grdMaster_RowDataBound(ByVal sender
As Object,
ByVal e As
System.Web.UI.WebControls.GridViewRowEventArgs)
Handles grdMaster.RowDataBound
Dim objListItem As
DataControlRowState
objListItem = e.Row.RowState
Dim intMAsterID1 As
Integer
If e.Row.RowType = DataControlRowType.DataRow
Then
Dim grd As
GridView
If objListItem = 5
Then
grd = CType(e.Row.FindControl("grdChildGridEdit"),
GridView)
MasterTableID = Convert.ToInt32(CType(e.Row.DataItem,
DataRowView).Row.ItemArray(0).ToString())
intMAsterID1 = MasterTableID
ElseIf objListItem =
DataControlRowState.Normal Or objListItem =
DataControlRowState.Alternate Then
grd = CType(e.Row.FindControl("grdChildGridNormal"),
GridView)
intMAsterID1 = Convert.ToInt32(CType(e.Row.DataItem,
DataRowView).Row.ItemArray(0).ToString())
Dim lnkButtton As
LinkButton
lnkButtton = CType(e.Row.FindControl("Edit"),
LinkButton)
If lnkButtton IsNot
Nothing Then
lnkButtton.CommandName = "Edit Master"
lnkButtton.CommandArgument = intMAsterID1.ToString
End If
ElseIf objListItem = DataControlRowState.Edit
Then
grd = CType(e.Row.FindControl("grdChildGridEdit"),
GridView)
MasterTableID = Convert.ToInt32(CType(e.Row.DataItem,
DataRowView).Row.ItemArray(0).ToString())
intMAsterID1 = MasterTableID
End If
If grd IsNot
Nothing Then
grd.DataSourceID = ""
grd.DataSource = ChildDataSource
ChildDataSource.SelectParameters("MasterTableID").DefaultValue
= intMAsterID1
ChildDataSource.Select()
grd.DataBind()
End If
End If
End
Sub
Here what I am doing is when master table's each row
bind with the GridView's row I am finding the ChildGrid Control then binding
that control with ChildDataSource for that MasterID.
Above code will be used when user hits on Master Grid
Edit button. So In the Template Column child grid with edit and delete option
will get visible. Now, the biggest problem with this child grid is that each and
every event you to write manually because grid will lost it's binding when any
command is get fired. And another thing is that unlike ASP.Net1.1's datagrid
child grid's handler will get called when any command of childgird get fired
like Edit, Delete, Sorting, Paging. In ASP.Net1.1 Data grid's Inner control's
event will be first handled by Grid's Item Command event irrespective of whether
that control is DataGrid, Button, List Box etc. But here it will not call the
RowCommand event of Master Grid it will directly call RowCommand event of
ChildGrid. So event flow is like this
1. When User Press Edit Command is Master Grid it will
call RowCommand Event of MasterGrid with Command Name as "Edit".
2. Now it will call RowDataBound of Mastergrid here you
will find the whether the RowState of particular Row is edit then you will find
ChildGrid with Edit and Delete Command in the EditTempalate of Template Column.
And Bind the grid to ChildDataSource.
3. Now, MasterGrid will look like below:
4. When you press EditCommand of ChildGrid it will
RowCommand of ChildGrid unlike ASP.Net1.1 's Datagrid call the ItemCommand of
Mastergrid. And it will not call the RowDataBound of MasterGrid so your child
edit grid for that particular row will not bind to datasource. So your grid will
get disappear. Now, here you in RowCommand of child grid you have to rebind the
grid with the datasource.
grdchildgrid = CType(sender, GridView)
If e.CommandArgument
IsNot Nothing
Then
If IsNumeric(e.CommandArgument)
Then
intRowId = Convert.ToInt32(e.CommandArgument)
End If
End If
If e.CommandName.Equals("Edit")
Then
grdchildgrid.DataSourceID = ""
grdchildgrid.DataSource = ChildDataSource
ChildDataSource.SelectParameters("MasterTableID").DefaultValue
= MasterTableID
ChildDataSource.Select()
End If
If e.CommandName.Equals("Update")
Then
UpdateChildRecord()
grdchildgrid.DataSourceID = ""
grdchildgrid.DataSource = ChildDataSource
ChildDataSource.SelectParameters("MasterTableID").DefaultValue
= MasterTableID
ChildDataSource.Select()
End If
If e.CommandName.Equals("Delete")
Then
DeleteChildRecord()
grdchildgrid.DataSourceID = ""
grdchildgrid.DataSource = ChildDataSource
ChildDataSource.SelectParameters("MasterTableID").DefaultValue
= MasterTableID
ChildDataSource.Select()
End If
If e.CommandName.Equals("Cancel")
Then
grdchildgrid.DataSourceID = ""
grdchildgrid.DataSource = ChildDataSource
ChildDataSource.SelectParameters("MasterTableID").DefaultValue
= MasterTableID
ChildDataSource.Select()
End If
If e.CommandName.Equals("Page")
Then
grdchildgrid.EditIndex = -1
grdchildgrid.DataSourceID = ""
grdchildgrid.DataSource = ChildDataSource
ChildDataSource.SelectParameters("MasterTableID").DefaultValue
= MasterTableID
ChildDataSource.Select()
End If
If e.CommandName.Equals("Sort")
Then
grdchildgrid.EditIndex = -1
Dim dt As
DataView
grdchildgrid.DataSourceID = ""
ChildDataSource.SelectParameters("MasterTableID").DefaultValue
= MasterTableID
dt = CType(ChildDataSource.Select(), DataView)
If ViewState.Item("SortDirection")
IsNot Nothing
Then
If CType(ViewState.Item("SortDirection"),
SortDirection) = SortDirection.Ascending Then
dt.Sort = e.CommandArgument & " ASC"
ViewState.Item("SortDirection") =
SortDirection.Descending
Else
dt.Sort = e.CommandArgument & " DESC"
ViewState.Item("SortDirection") =
SortDirection.Ascending
End If
End If
grdchildgrid.DataSource = dt
grdchildgrid.DataBind()
End
If
Here you will find that you have to handle every
command manually for the child grid because you are continuously changing
binding of child grid. And one thing I have found that if you did not write
handler of edit, delete, update, sort, page command it will give error because
when you press Edit Command of Child Grid it will find for the RowEditing
Handler of child grid even if you are doing your all the activity in RowCommand
event.
5. Here one thing is important is that in RowCommand
event of Child Grid you will get the old values in the grid means viewstate of
the grid. But the childgrid will not be bind to any data source if you don't
bind it to in RowCommand event.
6. When you press UpdateCommand it will call RowCommand
with CommandArgument as "Update". And after it will call the RowUpdating event
of the ChildGrid. But there no values will be there in either e.NewValues or
e.OldValues.
Points of Interest
ASP.NET 2.0 is very good to work with. It is so much
enhanced version and very much handy to work.
MSDN LINK
History
This is first version of GridControl. I will release
few more interesting articles on ASP.Net 2.0. If any body has any typical
problem in Datagrid I will try to work out on that.