Well since I couldn’t use a different datagrid than the one provided by Microsoft I decided to build a datagrid with some basic functionality. At least delete, insert, update e.t.c. should be supported. So this is my extended datagrid. Please if you have suggestions send me a message. I will appreciate the feedback. And sorry for the not so good writing.
The developed grid is a web server control and is coded in Visual Basic (sorry my C# friends). So let us take it form the beginning.
Just start Visual Studio and point to Visual Basic projects and to “Web Control Library”. Let name our project CustomDatagrid. Delete all the default code which is generated by Visual Studio. It is common wisdom that our grid will inherit from the Datagrid so just after the necessary imports define the class inherited form Datagrid.
Imports System.ComponentModel
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Public Class CustomdataGrid
Inherits DataGrid
End Class We want also the grid to fire up some events when doing some action and catch those events from the form. These events are commanddelete (for deleting a record), commandedit (for editing a record) and so forth. Moreover we are interested of some properties like CacheString (it is going to be used for caching the datasource), MyDataSource (used to set the datasource as a datatable), deletecolumnNumber (to set which column is the “delete” column).
'Declare Events for trapping them from the form
Public Event CommandDelete(ByRef deleted As Boolean, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
Public Event CommandEdit()
Public Event Cancel()
Public Event Addrecord(ByRef successfull As Boolean, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
Public Event Updaterecord(ByRef successfull As Boolean, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
Public Event SetDataSource()
'For private use
Private table As New DataTable
'.....
Private _MyDataSource As DataTable
Private _DeleteColumnNumber As Integer
Private _EditColumnNumber As Integer
Private _CacheString As String
'Properties
Public Property CacheString() As String
Get
Return _CacheString
End Get
Set(ByVal Value As String)
_CacheString = Value
End Set
End Property
Public Property EditColumnNumber() As Integer
Get
Return _EditColumnNumber
End Get
Set(ByVal Value As Integer)
_EditColumnNumber = Value
End Set
End Property
Public Property DeleteColumnNumber() As Integer
Get
Return _DeleteColumnNumber
End Get
Set(ByVal Value As Integer)
_DeleteColumnNumber = Value
End Set
End Property
Public Property MyDataSource() As DataTable
Get
Return _MyDataSource
End Get
Set(ByVal Value As DataTable)
_MyDataSource = Value
End Set
End PropertyWe simply want the grid to be render in the beginning so:
'Render the grid
Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)
MyBase.Render(output)
End SubWe want ot be able to clear the Cache:
Public Sub ClearCache()
'Clear cache
HttpContext.Current.Cache.Remove(_CacheString)
End SubTo bind the grid:
Sub BindGrid()
'bind the grid
If Not HttpContext.Current.Cache.Get(_CacheString) Is Nothing Then
Dim dgCache As DataSet
dgCache = HttpContext.Current.Cache.Get(_CacheString)
'grid
Me.MyDataSource = dgCache.Tables(0)
Else
'Me.MyDataSource = Me.DataSource.tables(0)
End If
Me.DataSource = CreateDataSource()
Me.DataBind()
Me.Visible = True
End SubAnd to handle events like insert, delete, update e.t.c.
So the whole class becomes the following:
Imports System.ComponentModel
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Public Class CustomdataGrid
Inherits DataGrid
'Declare Events for trapping them from the form
Public Event CommandDelete(ByRef deleted As Boolean, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
Public Event CommandEdit()
Public Event Cancel()
Public Event Addrecord(ByRef successfull As Boolean, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
Public Event Updaterecord(ByRef successfull As Boolean, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
Public Event SetDataSource()
'For private use
Private table As New DataTable
'.....
Private _MyDataSource As DataTable
Private _DeleteColumnNumber As Integer
Private _EditColumnNumber As Integer
Private _CacheString As String
'Properties
Public Property CacheString() As String
Get
Return _CacheString
End Get
Set(ByVal Value As String)
_CacheString = Value
End Set
End Property
Public Property EditColumnNumber() As Integer
Get
Return _EditColumnNumber
End Get
Set(ByVal Value As Integer)
_EditColumnNumber = Value
End Set
End Property
Public Property DeleteColumnNumber() As Integer
Get
Return _DeleteColumnNumber
End Get
Set(ByVal Value As Integer)
_DeleteColumnNumber = Value
End Set
End Property
Public Property MyDataSource() As DataTable
Get
Return _MyDataSource
End Get
Set(ByVal Value As DataTable)
_MyDataSource = Value
End Set
End Property
'Render the grid
Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)
MyBase.Render(output)
End Sub
'create the datasoure for the grid
Function CreateDataSource() As ICollection
Try
If _MyDataSource.Rows.Count > 0 Then
Dim dv As DataView
dv = _MyDataSource.DefaultView
CreateDataSource = dv
Else
End If
Catch ex As Exception
Throw ex
Finally
End Try
End Function
'inserting a new row in the grid for new record
Public Sub NewRecord()
Me.EditItemIndex = 0
'Move to the first page of the grid
Me.CurrentPageIndex = 0
'Hide Delete
Me.Columns(_DeleteColumnNumber).Visible = False
'Change the text of the "edit" column
Dim ecc As EditCommandColumn
ecc = Me.Columns(EditColumnNumber)
ecc.UpdateText = "Insert"
'setting up a private datatable
Fill()
'inserting a new row to the datatable
InsertEmptyRow(table)
'bind to grid
Bind()
End Sub
Private Function InsertEmptyRow(ByVal dttable As DataTable) As DataTable
'Insert empty row in the beginning of the grid
dttable.Rows.InsertAt(table.NewRow(), 0)
For i As Integer = 0 To dttable.Columns.Count - 1
dttable.Rows(0).Item(i) = ""
Next
Return dttable
End Function
Private Sub Fill()
'please clear tin cache
ClearCache()
'Please give me my datasource again in the Cache
RaiseEvent SetDataSource()
Dim myds As DataSet
myds = HttpContext.Current.Cache.Get(_CacheString)
table = myds.Tables(0)
End Sub
Private Sub Bind()
'Bind the grid to the datasource
Me.DataSource = table
Me.DataBind()
End Sub
Private Sub CustomdataGrid_PageIndexChanged(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles MyBase.PageIndexChanged
Me.CurrentPageIndex = e.NewPageIndex
BindGrid()
End Sub
Public Sub CustomdataGrid_EditCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles MyBase.EditCommand
'$$$$$$$$
'I am going to edit the record (do you want something to be done before that?)
RaiseEvent CommandEdit()
'$$$$$$$
Dim myds As DataSet
myds = HttpContext.Current.Cache.Get(_CacheString)
Me.MyDataSource = myds.Tables(0)
' begin editing
Me.EditItemIndex = e.Item.ItemIndex
'Bind the grid
BindGrid()
'Delete should not be visible
Me.Columns(_DeleteColumnNumber).Visible = False
End Sub
Public Sub CustomdataGrid_CancelCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles MyBase.CancelCommand
'Please clear the cache
ClearCache()
'I am going to cancel (do you want something to be done before that?)
RaiseEvent Cancel()
'Please give me my datasource again
RaiseEvent SetDataSource()
Me.EditItemIndex = -1
'Bind the grid
BindGrid()
'Delete should be visible now
Me.Columns(_DeleteColumnNumber).Visible = True
'Change the column text
Dim ecc As EditCommandColumn
ecc = Me.Columns(_EditColumnNumber)
ecc.UpdateText = "Update"
End Sub
Public Overridable Sub CustomdataGrid_DeleteCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles MyBase.DeleteCommand
Dim isLastOfThePage As Boolean
'Is this the last record?
If Me.Items.Count = 1 Then
isLastOfThePage = True
End If
Dim isdeleted As Boolean
'To know if the record has been deleted
'$$$$$
'Please delete the record
RaiseEvent CommandDelete(isdeleted, e)
'$$$$$
If isdeleted Then
'Deleted succesfully so lets go now
If isLastOfThePage Then Me.CurrentPageIndex = 0
'clear cache
ClearCache()
Me.EditItemIndex = -1
'Give me my know datasource
RaiseEvent SetDataSource()
'Bind the grid
BindGrid()
'Delete is now visible
Me.Columns(_DeleteColumnNumber).Visible = True
End If
End Sub
Private Sub CustomdataGrid_UpdateCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles MyBase.UpdateCommand
Dim successfull As Boolean
Dim myds As DataSet
Dim mydataTable As DataTable
myds = HttpContext.Current.Cache.Get(_CacheString)
mydataTable = myds.Tables(0)
Me.MyDataSource = myds.Tables(0)
If _MyDataSource.Rows(e.Item.ItemIndex).RowState = DataRowState.Added Then
'New record - add it please
RaiseEvent Addrecord(successfull, e)
Else
'update record - update it please
RaiseEvent Updaterecord(successfull, e)
End If
If successfull Then
'All done succesfully
Me.EditItemIndex = -1
'clear cache
ClearCache()
'Give me my new datasource
RaiseEvent SetDataSource()
'Bind the grid
BindGrid()
'Delete is now visible
Me.Columns(_DeleteColumnNumber).Visible = True
'Change the edit column text
Dim ecc As EditCommandColumn
ecc = Me.Columns(_EditColumnNumber)
ecc.UpdateText = "Update"
End If
End Sub
Public Sub ClearCache()
'Clear cache
HttpContext.Current.Cache.Remove(_CacheString)
End Sub
Sub BindGrid()
'bind the grid
If Not HttpContext.Current.Cache.Get(_CacheString) Is Nothing Then
Dim dgCache As DataSet
dgCache = HttpContext.Current.Cache.Get(_CacheString)
'grid
Me.MyDataSource = dgCache.Tables(0)
Else
'Me.MyDataSource = Me.DataSource.tables(0)
End If
Me.DataSource = CreateDataSource()
Me.DataBind()
Me.Visible = True
End Sub
End Class Please note that when an action occurs our grid fires some events that should be cached from the form. Like the “SetDataSource” which as it says sets the datasource. Now that we are done just build the project and the custom grid is ready for production.
Now let us use it in a simple project. Create a new web project and reference the grid. Select "add existing project" to the solution and add the grid project. To add the grid in the web form just register it:
<%@ Register TagPrefix="MyGrid" Namespace="CustomDataGrid" Assembly="CustomDataGrid" %>And add it to the page:
<MyGrid:CustomDataGrid id="CustomdataGrid1" runat="server"></MyGrid:CustomDataGrid>Next set some columns (delete and insert columns too). Let's say we will add three columns categoryid, categoryname and description and the edit and delete column.
Don’t forget to clear the “Create columns automatically at run time”.
There are some basic things which we have to point if we want to use this grid. First of all every time we load the web form we must set the numbers of the delete, edit columns, the string in which name we will store the datasource in cache and to bind the grid if there is already a datasource.
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
If Not IsPostBack Then
'Do something here
End If
'set grid
SetGrid()
End Sub'Setting the grid
Private Sub SetGrid()
Me.CustomdataGrid1.EditColumnNumber = 3 'the number of the edit column
Me.CustomdataGrid1.DeleteColumnNumber = 4 'the number of the delete column
Me.CustomdataGrid1.CacheString = xxxxxx 'xxx: Cachestring
If Not Cache(xxxx) Is Nothing Then
Dim myds As DataSet
myds = Cache(xxxxx) 'xxx: Cachestring
Me.CustomdataGrid1.MyDataSource = myds.Tables(0)
End If
End SubNotice that we clear the cache, then get the datasource (for example a select statement (which will also handle the CustomdataGrid1.SetDataSource event) and inside there we will cache the datasource and the we bind the grid. A typical GetDataSource function would be:
Private Sub GetDatSource() Handles CustomdataGrid1.SetDataSource
Try
'Here the code for getting the datasource
If xxxxx Then 'if we got the datasource
'!!!!!!!!!!!!!!!!!!!!!!!
'Inserting into cache
Cache.Insert("xxxxx", myds, Nothing, _
DateTime.Now.AddMinutes(15), TimeSpan.Zero)
'xxx: Cachestring
'myds: the dataset
Else
myds = Cache("xxx") 'here the cachestring
End If
Catch ex As Exception
Finally
End Try
End SubFollowing the same we write functions for the events thrown by the grid:
Private Sub Cancel() Handles CustomdataGrid1.Cancel
'Something here
End Sub
Private Sub Edit() Handles CustomdataGrid1.CommandEdit
'Something here
End Sub
Private Sub Delete(ByRef Deleted As Boolean, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles CustomdataGrid1.CommandDelete
If ‘delete the record here Then
Deleted = True
Else
Deleted = False
End If
End Sub
Private Sub AddsRecord(ByRef successfull As Boolean, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles CustomdataGrid1.Addrecord
If ‘Add the record here Then
successfull = True
End If
End Sub
Private Sub Updaterecord(ByRef successfull As Boolean, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles CustomdataGrid1.Updaterecord
If ‘Update the record here Then
successfull = True
End If
End Sub
And a find button to get the datasource
Private Sub find_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles find.Click
'clear cache
Me.CustomdataGrid1.ClearCache()
GetDatSource()
'Kano bind to grid
Me.CustomdataGrid1.BindGrid()
End SubThat was all. Please let me remind you again if you have suggestions send me a message.