With .NET 2.0 now being official it was only a given for me to convert the code for .NET 2.0's Gridview. Before I present the updated code, I'll now discuss the changes that have occurred in converting the code from a DataGrid to a GridView.
First off, the code-behind model has changed. In the @Page directive, accessing your code behind is accomplish via the CodeFile attribute instead of the Codebehind or Src attribute. Also much of the used to DataGrid properties have changed, as seen below:
.NET
1.1 DataGrid
|
.NET
2.0 GridView
|
|
CurrentPageIndex
|
-->
|
PageIndex
|
OnPageIndexChanged
|
-->
|
OnPageIndexChanging
|
OnSortCommand
|
-->
|
OnSorting
|
DataKeyField
|
-->
|
DataKeyNames
|
SelectedItemStyle
|
-->
|
SelectedRowStyle
|
ItemStyle
|
-->
|
RowStyle
|
TemplateColumn
|
-->
|
TemplateField
|
BoundColumn
|
-->
|
BoundField
|
DataGrid.Items
|
-->
|
GridView.Rows
|
DataGridItem
|
-->
|
GridViewRow
|
DataGridItem (ItemIndex)
|
-->
|
GridViewRow (RowIndex).Value
|
DataGridPageChangedEventArgs
|
-->
|
GridViewPageEventArgs
|
DataGridSortCommandEventArgs
|
-->
|
GridViewSortEventArgs
|
The CurrentPageIndex which gets or sets the index of the currently displayed page is now simply PageIndex. Setting up paging and sorting in the Gridview has changed from the OnPageIndexChanged and OnSortCommand methods to OnPageIndexChanging and OnSorting, respectively. The primary key field for the items displayed in the GridView has also changed from DataKeyField to DataKeyNames property.
Setting up row colors on the grid is no more SelectedItemStyle or ItemStyle but rather SelectedRowStyle and RowStyle. I guess this makes more sense since it is a row, anyway. The TemplateColumn class that displays custom content in a data-bound control is now TemplateField, and its partner the BoundColumn which represents a field that is displayed as text in a data-bound control is now called BoundField.
Next, in our code-behind, .NET 2.0 utilizes a new language feature known as a Partial. A Partial class is just that, a partial, incomplete definition of the class or structure. So all that is included in the partial class in only the code needed, such as event handlers and the like. .NET infers the control instances and it derives the events bound from the .aspx file during compilation. Notice in the codebehind I didn't have to declare the GridView or the OutputMsg controls there, as I did in the DataGrid version, neither did I need to include most of the Imports statements that were there before!
Another change in the framework went to the RegisterClientScriptBlock method, this now obsolete method needs to be ClientScript.RegisterClientScriptBlock (Type type, string key, string script) or in our code ClientScript.RegisterClientScriptBlock (Me.GetType(),"clientScript", jsScript.ToString()).
As for implementing custom paging, this also has changed its class wording from DataGridPageChangedEventArgs to GridViewPageEventArgs.
Also, when we retrieve the key value of each record based on DataGrids DataKeyField property we set up the loop like so:
For Each dgItem In MyDataGrid.Items
'Retrieve key value of each record based on DataGrids DataKeyField property
ChkBxIndex = MyDataGrid.DataKeys(dgItem.ItemIndex)
Next
Accomplishing the same now needs to use the GridView's DataKeyNames property and the DataGridItem's ItemIndex is now the GridViewRow's RowIndex Value:
'Loop through GridView Items
For Each dgItem In MyGridView.Rows
'Retrieve key value of each record based on GridViews DataKeyNames property
ChkBxIndex = MyGridView.DataKeys(dgItem.RowIndex).Value
Next
And aside from changing every instance of the word DataGrid to GridView, as for this article that's about it. So here's the code in its .NET 2.0 entirety, with row color state. Enjoy!
Main Page
<%@ Page Language="VB" Strict="True" Explicit="True" Buffer="True"
Debug="False" Trace="False" CodeFile="mGridView.aspx.vb"
Inherits="MultiDeleteDG.WebForm" AutoEventWireup="True"
EnableSessionState="True" %>
<html>
<head></head>
<body>
<form runat="server">
<h3>Selecting, Confirming & Deleting Multiple Checkbox Items In A GridView (i.e. HotMail & Yahoo) -<br>
Part 2: Maintaining CheckBox State Across Pages with Sorting </h3>
<br />
Current Page: <%=MyGridView.PageIndex +1%> <br />
<ASP:GridView id="MyGridView" runat="server"
Width="700"
BackColor="white"
BorderColor="black"
CellPadding="3"
CellSpacing="0"
Font-Size="9pt"
AutoGenerateColumns="False"
HeaderStyle-BackColor="darkred"
HeaderStyle-ForeColor="white"
AllowPaging="True"
AllowCustomPaging="False"
AllowSorting="True"
OnPageIndexChanging="MyGridView_Page"
OnSorting="MyGridView_Sort"
PageSize="10"
PagerStyle-Mode="NumericPages"
PagerStyle-HorizontalAlign="Right"
DataKeyNames="ID">
<SelectedRowStyle BackColor="#F5EDED" ForeColor="Black" />
<RowStyle BackColor="White" ForeColor="Black" />
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="CheckAll" OnClick="javascript: highlightChkBxRow(this);
return select_deselectAll (this.checked, this.id);" runat="server" />
<font face="Webdings" color="white" size="4">a</font>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="DeleteThis" OnClick="javascript: highlightChkBxRow(this);
return select_deselectAll (this.checked, this.id);" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="StoreID" SortExpression="ID asc" Datafield="ID" runat="server" />
<asp:BoundField HeaderText="Store" SortExpression="Company asc" Datafield="Company" runat="server" />
<asp:BoundField HeaderText="Address" SortExpression="Address asc" Datafield="Address" runat="server" />
<asp:BoundField HeaderText="City" SortExpression="City asc" Datafield="City" runat="server" />
<asp:BoundField HeaderText="State" SortExpression="State asc" Datafield="State" runat="server" />
<asp:BoundField HeaderText="Zip" SortExpression="Zip asc" Datafield="Zip" runat="server" />
</Columns>
</ASP:GridView>
<br />
<asp:Button id="Confirm" onclick="DeleteAllIds" runat="server" Text="Delete Items" />
<asp:Button id="ClearAll" onclick="ClearGridView" runat="server" Text="Clear All" />
<span id="OutputMsg" runat="server" EnableViewState="false" />
</form>
</body>
</html>
The Code-Behind
Imports System.Data
Imports System.Data.SQLClient
Namespace MultiDeleteDG
Partial Class WebForm
Inherits System.Web.UI.Page
Protected CheckBox As System.Web.UI.WebControls.CheckBox
Protected objConnect As SqlConnection
Protected myDataAdapter As SqlDataAdapter
Protected myCommand As SqlCommand
Protected DS as Dataset
Protected dgItem As GridViewRow
Public deletedIds As String = ""
Public ChkdItems As String = ""
Public SortField As String = ""
Public ChkBxIndex As String = ""
Public BxChkd As Boolean = False
Public CheckedItems As ArrayList
Public Results() As String
Sub Page_PreRender (ByVal Sender As Object, ByVal E As EventArgs)
Dim nl As String = Environment.NewLine
Dim jsScript As New StringBuilder ()
With jsScript
.Append ("<script language=JavaScript>" & nl)
.Append ("<!--" & nl & nl)
.Append ("function confirmDelete (frm) {" & nl & nl)
.Append (" // loop through all elements" & nl & nl)
.Append (" for (i=0; i<frm.length; i++) {"& nl & nl)
.Append (" // Look for our checkboxes only" & nl)
.Append (" if (frm.elements[i].name.indexOf ('DeleteThis') !=-1) {" & nl & nl)
.Append (" // If any are checked then confirm alert, otherwise nothing happens" & nl)
.Append (" if(frm.elements[i].checked) {" & nl & nl)
.Append (" return confirm ('Are you sure you want to delete your selection(s)?')" & nl & nl)
.Append (" }" & nl)
.Append (" }" & nl)
.Append (" }" & nl)
.Append (" }" & nl & nl)
.Append ("/*Using modified select_deselectAll script function of my original one,")
.Append (" from Developerfusion.com forum members - ketcapli & thombo")
.Append (" Forum Post - [http://www.developerfusion.co.uk/forums/topic-22773]*/")
.Append ("function select_deselectAll (chkVal, idVal) {" & nl)
.Append (" var frm = document.forms[0];" & nl)
.Append (" if (idVal.indexOf('DeleteThis') != -1 && chkVal == true){" & nl)
.Append (" var AllAreSelected = true;" & nl)
.Append(" for (i=0; i<frm.length; i++) {" & nl)
.Append(" if (frm.elements[i].id.indexOf('DeleteThis') != -1 &&
frm.elements[i].checked == false){ " & nl)
.Append (" AllAreSelected = false;" & nl)
.Append (" break;" & nl)
.Append (" } " & nl)
.Append (" } " & nl)
.Append (" if(AllAreSelected == true){" & nl)
.Append (" for (j=0; j<frm.length; j++) {" & nl)
.Append (" if (frm.elements[j].id.indexOf ('CheckAll') != -1) {" & nl)
.Append (" frm.elements[j].checked = true;" & nl)
.Append (" break;" & nl)
.Append (" }" & nl)
.Append (" }" & nl)
.Append (" }" & nl)
.Append (" } else {" & nl)
.Append (" for (i=0; i<frm.length; i++) {" & nl)
.Append (" if (idVal.indexOf ('CheckAll') != -1) {" & nl)
.Append (" if(chkVal == true) {" & nl)
.Append (" frm.elements[i].checked = true; " & nl)
.Append (" } else {" & nl)
.Append (" frm.elements[i].checked = false; " & nl)
.Append (" }" & nl)
.Append (" } else if (idVal.indexOf('DeleteThis') != -1 &&
frm.elements[i].checked == false) {" & nl)
.Append (" for (j=0; j<frm.length; j++) {" & nl)
.Append (" if (frm.elements[j].id.indexOf ('CheckAll') != -1) { " & nl)
.Append (" frm.elements[j].checked = false;" & nl)
.Append (" break; " & nl)
.Append (" } " & nl)
.Append (" } " & nl)
.Append (" } " & nl)
.Append (" } " & nl)
.Append (" } " & nl)
.Append (" } " & nl & nl)
.Append ("function highlightChkBxRow(chkbx) {" & nl & nl)
.Append (" if (chkbx.id.indexOf ('DeleteThis') != -1) {" & nl & nl)
.Append (" if (chkbx.checked) {" & nl & nl)
.Append (" chkbx.parentElement.parentElement.style.backgroundColor='#F5EDED';" & nl)
.Append (" chkbx.parentElement.parentElement.style.color='#000000';" & nl)
.Append (" } else {" & nl & nl)
.Append (" chkbx.parentElement.parentElement.style.backgroundColor='#FFFFFF';" & nl)
.Append (" chkbx.parentElement.parentElement.style.color='#000000';" & nl & nl)
.Append (" }" & nl & nl)
.Append (" } else {" & nl & nl)
.Append (" var frm = document.forms[0];" & nl & nl)
.Append (" for (h = 0; h < frm.length; h++) {" & nl & nl)
.Append (" if (frm.elements[h].id.indexOf ('DeleteThis') != -1) {" & nl & nl)
.Append (" if (chkbx.id.indexOf ('CheckAll') != -1 && chkbx.checked) {" & nl & nl)
.Append (" frm.elements[h].parentElement.parentElement.style.backgroundColor='#F5EDED';" & nl)
.Append (" frm.elements[h].parentElement.parentElement.style.color='#000000';" & nl & nl)
.Append (" } else {" & nl & nl)
.Append (" frm.elements[h].parentElement.parentElement.style.backgroundColor='#FFFFFF';" & nl)
.Append (" frm.elements[h].parentElement.parentElement.style.color='#000000';" & nl & nl)
.Append (" }" & nl)
.Append (" }" & nl)
.Append (" } //loop" & nl)
.Append (" }" & nl)
.Append ("}" & nl)
.Append ("//--> " & nl & nl)
.Append ("</scr" & "ipt>")
End With
ClientScript.RegisterClientScriptBlock (Me.GetType(),"clientScript",_
jsScript.ToString())
jsScript = Nothing
Dim button As WebControl = CType(Page.FindControl("Confirm"), WebControl)
button.Attributes.Add("onclick", "return confirmDelete (this.form);")
End Sub
Sub Page_Load (ByVal Sender As Object, ByVal E As EventArgs)
objConnect = New SqlConnection("server=(local);database=Northwind;uid=sa;pwd=;")
If Not IsPostBack Then
Session.Clear()
'Set up default column sorting
If IsNothing(Session ("SortOrder")) Then
BindData ("ID asc")
Else
BindData (Session ("SortOrder"))
End If
End If
End Sub
Sub MyGridView_Page (sender As Object, e As GridViewPageEventArgs)
'Get CheckBoxValues before paging occurs
GetCheckBoxValues()
MyGridView.PageIndex = e.NewPageIndex
BindData(Session ("SortOrder"))
'Populate current GridView page with the current page items from Session after databind
RePopulateCheckBoxes ()
End Sub
Sub GetCheckBoxValues() 'As paging occurs store checkbox values
CheckedItems = New ArrayList
'Loop through GridView Items
For Each dgItem In MyGridView.Rows
'Retrieve key value of each record based on GridViews DataKeyNames property
ChkBxIndex = MyGridView.DataKeys(dgItem.RowIndex).Value
CheckBox = dgItem.FindControl("DeleteThis")
'Add ArrayList to Session if it doesnt exist
If Not IsNothing(Session ("CheckedItems")) Then
CheckedItems = Session ("CheckedItems")
End If
If CheckBox.Checked Then
BxChkd = True
'Add to Session if it doesnt already exist
If Not CheckedItems.Contains(ChkBxIndex) Then
CheckedItems.Add(ChkBxIndex.ToString())
End If
Else
'Remove value from Session when unchecked
CheckedItems.Remove(ChkBxIndex.ToString())
End If
Next
'Update Session with the list of checked items
Session ("CheckedItems") = CheckedItems
End Sub
Sub BindData (SortField As String)
'Setup Session Cache for different users
Dim Source As DataView = Session ("dgCache")
If (IsNothing (Source)) Then
Dim sqlQuery As String = "Select OrderId As Id, ShipName As Company," _
& " ShipAddress As Address, ShipCity As City, _
ShipCountry As State, ShipPostalCode As Zip from Orders"
myDataAdapter = New SqlDataAdapter(sqlQuery, objConnect)
DS = New Dataset()
myDataAdapter.Fill(DS, "MyGridView")
'Assign sort expression to Session
Session ("SortOrder") = SortField
'Setup DataView for Sorting
Source = DS.Tables(0).DefaultView
'Insert DataView into Session
Session ("dgCache") = Source
End If
Source.Sort = SortField
MyGridView.DataSource = Source
MyGridView.DataBind ()
'Close connection
objConnect.Close
End Sub
Sub RePopulateCheckBoxes ()
CheckedItems = New ArrayList
CheckedItems = Session ("CheckedItems")
If Not IsNothing(CheckedItems) Then
'Loop through GridView Items
For Each dgItem in MyGridView.Rows
ChkBxIndex = MyGridView.DataKeys(dgItem.RowIndex).Value
'Repopulate GridView with items found in Session
If CheckedItems.Contains(ChkBxIndex) Then
CheckBox = CType(dgItem.FindControl("DeleteThis"), CheckBox)
CheckBox.Checked = True
dgItem.ForeColor = MyGridView.SelectedRowStyle.ForeColor
dgItem.BackColor = MyGridView.SelectedRowStyle.BackColor
Else
dgItem.ForeColor = MyGridView.RowStyle.ForeColor
dgItem.BackColor = MyGridView.RowStyle.BackColor
End If
Next
End If
'Copy ArrayList to a new array
Results = CheckedItems.ToArray(GetType(String))
'Concatenate ArrayList with comma to properly send for deletion
deletedIds = String.Join(",", Results)
End Sub
Sub DeleteAllIds (ByVal sender As Object, ByVal e As EventArgs)
'Regrab values in case the deletion occurs on the given page and any checkboxes were unchecked
'on the current page without any postback to correct the values in Session
GetCheckBoxValues ()
If BxChkd = True Then
RePopulateCheckBoxes ()
'Delete the rows of data containing the checkbox values
Dim deleteSQL As String = "DELETE from Orders WHERE OrderId IN (" + deletedIds + ");"
myCommand = New SqlCommand (deleteSQL, objConnect)
With myCommand
.Connection.Open()
.ExecuteNonQuery()
End With
'Close connection
objConnect.Close()
OutputMsg.InnerHtml += "<font size=4><b>Store information has been deleted.</b></font>"
OutputMsg.Style("color") = "green"
'Clear all Session values
Session.Clear()
'Reset GridView to top
MyGridView.PageIndex = 0
BindData (Session ("SortOrder"))
End If
End Sub
Function SortOrder (Field As String) As String
Dim so As String = Session ("SortOrder")
If Field = so Then
SortOrder = Replace (Field,"asc","desc")
ElseIf Field <> so Then
SortOrder = Replace (Field,"desc","asc")
Else
SortOrder = Replace (Field,"asc","desc")
End If
'Maintain persistent sort order
Session ("SortOrder") = SortOrder
End Function
Sub MyGridView_Sort (Sender As Object, E As GridViewSortEventArgs)
'To retain checkbox on sorting
GetCheckBoxValues ()
MyGridView.PageIndex = 0 'To sort from top
BindData (SortOrder (E.SortExpression).ToString()) 'Rebind our GridView
'To retain checkbox on sorting
RePopulateCheckBoxes ()
End Sub
Sub ClearGridView (ByVal sender As Object, ByVal e As EventArgs)
'Clear All Session Values
Session.Clear()
'Reset GridView to top
MyGridView.PageIndex = 0
BindData ("ID asc") 'Rebind our GridView
End Sub
End Class
End Namespace
Comments