Creating Custom GridView Control
Posted by Ravi Varma Thumati on October 28, 2009
In this article, we will examines the creation of a new custom GridView control from scratch, which allows the developer to include a checkbox column to the GridView control automatically with embedded JavaScript code to check/uncheck the checkbox column without the need to write any bit of code. He begins with comprehensive coverage of the steps involved in customization of the GridView class and implementation of template classes. Towards the end of the article, Abdulla examines the usage of the control with Visual Studio 2005. The article also covers how to embed a JavaScript file with a custom control and how to use it later on with the help of detailed analysis, relevant source code, and screenshots.
Article Contents:
- Customizing the GridView Class
- Supporting Client Side Functionality
- Implementing Templates Classes
- Using the Control
- Conclusion
Customizing the GridView Class
Let us begin creating our new custom GridView control, open your Visual Studio then create a new Class library project and name it as “MyCustomControl.”
First of all, you have to add some references to allow you to use the needed namespaces and classes, below are the needed references:
1. System.Design
2. System.Drawing
3. System.Web
4. System.Web.Extensions
5. System.Web.Extensions.Design
Then create a new class and name it “CustomGrid.”
Inheriting the GridView class is much better than creating a new databound control from scratch, that give us the benefits of functions and subroutines already existing in the GridView class.
Listing 1
<Assembly: TagPrefix("MyCustomControl.CustomsControls", "asp")>
<Assembly: WebResource("MyCustomControl.CustomGridJS.js", "text/javascript")>
Namespace CustomsControls
<ToolboxData("<{0}:CustomGrid runat=""server""></{0}:CustomGrid>")> _
Partial Public Class CustomGrid
Inherits GridView
'My Code Here
End Class
We will create a property for including the checkbox column to allow the developer to add the column automatically, which is implemented in Listing 2.
Listing 2
''' <summary>
''' Add checkbox column to the gridview.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
<Category("Behavior")> _
<Description("Add checkbox column to the gridview.")> _
<DefaultValue(False)> _
Public Property IncludeColumnCheckBox() As Boolean
Get
If String.IsNullOrEmpty(ViewState("IncludeColumnCheckBox")) Then
Return False
Else
Return DirectCast(ViewState("IncludeColumnCheckBox"), Boolean)
End If
End Get
Set(ByVal Value As Boolean)
ViewState("IncludeColumnCheckBox") = Value
End Set
End Property
Now we will override the CreateColumns function which is responsible for creating the columns, and there we will add our new checkbox column, as in Listing 3.
Listing 3
Protected Overrides Function CreateColumns(ByVal dataSource As PagedDataSource, _
ByVal useDataSource As Boolean) As ICollection
Dim columnList As ICollection = MyBase.CreateColumns(dataSource, useDataSource)
If Not IncludeColumnCheckBox Then
Return columnList
End If
Dim list As ArrayList = New ArrayList(columnList)
Dim _CheckBoxColumn As New MyTemplateField
list.Insert(0, _CheckBoxColumn)
Return list
End Function
You may note that I am declaring an object from a template class that I created before I called MyTemplateField, and that the GridView column consisted from the set of templates classes (Header, Item, Alternate and footer).
I will illustrate these templates classes in the Implementing Templates classes section,
Developers do not need to write multi lines of code to get the ID’s of the selected rows; we will return these ID’s simply by writing a new property called GetCheckedRows which is shown below.
Listing 4
''' <summary>
''' Return list of IDs joined with ',' separators
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
<Browsable(False)> _
Public ReadOnly Property GetCheckedRows() As String
Get
Dim _collectionIds As String = String.Empty
If DataKeys.Count > 0 Then
For i As Integer = 0 To Rows.Count - 1
If Rows(i).RowType = DataControlRowType.DataRow Then
If DirectCast(Rows(i).FindControl("ChkItem"), CheckBox).Checked Then
If _collectionIds = String.Empty Then
_collectionIds = DataKeys(Rows(i).RowIndex).Value
Else
_collectionIds & = "," & DataKeys(Rows(i).RowIndex).Value
End If
End If
End If
Next
End If
Return _collectionIds
End Get
End Property
Supporting Client Side Functionality
As I mention before, our new custom GridView control will support checking/unchecking the checkbox column in client-side using JavaScript functions embedded with the control, so we need to assign the JavaScript function to the checkbox element in the Header template of the GridView, and that occurs at the row created subroutine as illustrated in Listing 5.
Listing 5
Protected Overloads Overrides Sub OnRowCreated(ByVal e As GridViewRowEventArgs)
MyBase.OnRowCreated(e)
If IncludeColumnCheckBox Then
If e.Row.RowType = DataControlRowType.Header Then
DirectCast(e.Row.FindControl("ChkHeader"), CheckBox).Attributes.Add("onclick", _
"ObjJs_" & Me.ID & ".CheckUnCheckRows(this.checked)")
End If
End If
End Sub
We have to tell the Page that our custom control has JavaScript files that need to be registered when the final HTML is generated for that page. So we need to write a bit of code in the OnInit subroutine.
Listing 6
Protected Overrides Sub OnInit(ByVal e As EventArgs)
MyBase.OnInit(e)
Me.Page.ClientScript.RegisterClientScriptInclude(Me.GetType(), "CustomGridJS", _
Page.ClientScript.GetWebResourceUrl(Me.GetType(),
"MyCustomControl.CustomGridJS.js"))
End Sub
And we should declare a JavaScript object from the JavaScript file which contains the client side code as in Listing 7. Using this way allows us to drag and drop our new custom control many times in the page without worrying about confliction between these instances.
Listing 7
Public Overrides Sub Rendercontrol(ByVal writer As System.Web.UI.HtmlTextWriter)
MyBase.RenderControl(writer)
ScriptManager.RegisterStartupScript(Page, Me.GetType, Me.ID & "JSBlock", "var
ObjJs_" & Me.ID & " = new GridClass('" & Me.ClientID & "');", True)
End Sub
I recommend you download the source so that you can preview the JavaScript file which is responsible for the client side functionality.
Implementing Templates Classes
As I said before, the GridView column consists from the set of Template classes (Header, Item, Alternate and Footer). And in our case we need to implement two template classes (Header and Item templates).
Look at listing 8; I will use these two template classes in the constructor of the template field class, and we will create an object from that template field class.
Listing 8
'Header Template Class
NotInheritable Class MyHeaderTemplate
Implements ITemplate
Sub InstantiateIn(ByVal owner As Control) Implements ITemplate.InstantiateIn
Dim chkboxHeader As New CheckBox
chkboxHeader.ID = "ChkHeader"
owner.Controls.Add(chkboxHeader)
End Sub
End Class
'Item Template Class
NotInheritable Class MyItemTemplate
Implements ITemplate
Sub InstantiateIn(ByVal owner As Control) Implements ITemplate.InstantiateIn
Dim chkboxItem As New CheckBox
chkboxItem.ID = "ChkItem"
owner.Controls.Add(chkboxItem)
End Sub
End Class
Here we are setting the look and feel of the header and item template field for the checkbox column; as you can see we are setting the vertical and horizontal align for the header and item template.
Listing 9
Class MyTemplateField
Inherits TemplateField
Private _owner As TemplateOwner
Private _header As MyHeaderTemplate
Private _item As MyItemTemplate
Public Sub New()
_owner = New TemplateOwner
_header = New MyHeaderTemplate
_item = New MyItemTemplate
_header.InstantiateIn(_owner)
Me.HeaderTemplate = _header
_item.InstantiateIn(_owner)
Me.ItemTemplate = _item
Me.HeaderStyle.VerticalAlign = VerticalAlign.Middle
Me.HeaderStyle.HorizontalAlign = HorizontalAlign.Center
Me.HeaderStyle.Width = Unit.Percentage(3)
Me.ItemStyle.VerticalAlign = VerticalAlign.Middle
Me.ItemStyle.HorizontalAlign = HorizontalAlign.Center
End Sub
End Class
<ToolboxItem(False)> _
Public Class TemplateOwner
Inherits WebControl
End Class
Using the Control
To add the custom GridView control in your toolbox, follow the subsequent steps:
Right click on the toolbox window then choose “Add Tab.”
Type the name you want for the new tab, right click over it, and click “Choose Items.”
Click on the Browse button in the “.NET Framework Components” tab, go to the custom GridView project, open the bin folder, and choose MyCustomControl.dll.
The result is shown Figure 1.
Figure 1
Now drag the custom GridView control, go the properties window, and check the IncludeColumnCheckBox property, you will note that a new checkbox column has been added to the Gridview automatically.
Figure 2
View the page in a browser, and click the checkbox element in the GridView header row; you will note that all checkboxes are checked/unchecked Client side without the need from you to write any bit of code. And that is why Microsoft gives us the ability to create a new custom control!
Figure 3
Conclusion
In this article, I demonstrate how to create a custom GridView control and how to add a new checkbox column automatically. Also, we have learned how to embedded JavaScript file with custom controls and how to use it in the page.
In addition, we have learned how to create a template field classes and how to declare an object from these classes. I encourage you to download the source code so you can see all what we have done in more details.
Leave a comment