When clicking the pager in a GridView, I want to highlight each row if the amount equals a certain amount. I have this working when the GridView is first populated, but each time I click the pager button to move to the next page with a valid amount, it will not highlight. Any suggestions?
GridView
<asp:GridView ID="ERNDataGrid" runat="server" CssClass="clsGridView" AutoGenerateColumns="false" AllowPaging="true" PageSize="15"
OnPageIndexChanging="OnPageIndexChanging" OnRowDataBound="OnRowDataBound" Width="99%">
<HeaderStyle HorizontalAlign="Center" BackColor="#464646" Font-Bold="True" ForeColor="White"></HeaderStyle>
<PagerSettings Mode="NextPreviousFirstLast" />
<PagerStyle HorizontalAlign="Right" ForeColor="White" BackColor="#464646" Font-Bold="False" Font-Italic="False" Font-Overline="False" Font-Strikeout="False" Font-Underline="False"></PagerStyle>
<AlternatingRowStyle BackColor="#DDDDDD"></AlternatingRowStyle>
<Columns>
<asp:BoundField DataField="CUID" HeaderText="Routing Number" ItemStyle-HorizontalAlign="Center" />
<asp:BoundField DataField="Account" HeaderText="Account" ItemStyle-HorizontalAlign="Center" />
<asp:BoundField DataField="Amount" HeaderText="Amount" DataFormatString="{0:C}" ItemStyle-HorizontalAlign="Center" />
<asp:BoundField DataField="Serial" HeaderText="Check Number" ItemStyle-HorizontalAlign="Center" />
</Columns>
</asp:GridView>
VB.net Codebehind
Protected Sub ResearchGridView_Click(sender As Object, e As EventArgs) Handles ResearchGridView.Click
strResearchAmount = txtERNResearchAmount.Value
BindData()
End Sub
Private Sub ERNResearch_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
ERNDataGrid.DataBind()
End If
End Sub
Protected Sub BindData()
'Create a connection
Dim myConnection As New SqlConnection("This works")
'Create the command object, passing in the SQL string
Const strSQL As String = "SELECT CUID, Account, Amount / 100 as Amount, Serial FROM [ACCU].[dbo].[ERN_ITEM_VIEW] Where Date = '04/13/2017' And CUID <> '0'"
Dim myCommand As New SqlCommand(strSQL, myConnection)
'Create the DataAdapter
Dim myDA As New SqlDataAdapter()
myDA.SelectCommand = myCommand
'Populate the DataSet
Dim myDS As New DataSet()
myDA.Fill(myDS)
'Set the datagrid's datasource to the dataset and databind
ERNDataGrid.DataSource = myDS
ERNDataGrid.DataBind()
'Display Information on what page we are currently viewing
'lblMessage.Text = "Viewing Page " & ERNDataGrid.PageIndex + 1 & " of " & ERNDataGrid.PageCount
End Sub
Protected Sub OnPageIndexChanging(sender As Object, e As GridViewPageEventArgs)
ERNDataGrid.PageIndex = e.NewPageIndex
Me.BindData()
End Sub
Protected Sub OnRowDataBound(sender As Object, e As GridViewRowEventArgs)
If e.Row.RowIndex > -1 Then
If e.Row.Cells(2).Text = "$" & strResearchAmount Then
e.Row.BackColor = Color.Yellow
End If
End If
End Sub
Your code looks correct. The OnRowDataBound event is triggered every time DataBind() is called. And since that is the case in your OnPageIndexChanging the RowDataBound should fire.
However the strResearchAmount could be empty since it is filled only after a button click. Since a page index change also triggers a PostBack, it is likely that strResearchAmount is empty when OnRowDataBound is called for the second time.
Check the value of strResearchAmount and make sure it persists across PostBack.
Related
I want to add one button in vb.net e.g bulk approval outside the gridview in another table. While clicking on that button I.e is bulk approval.. all verify button are verified in gridview in every row... and changed into verified.
Ok, so we have some kind of grid, and some kind of approve button for each row.
Ok, so we have some typical markup like this:
This is a grid (hotel bookings), and then a the "administrator" has to approve each one.
So, say some markup like this - nothing special:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" ItemStyle-Width="180" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="Approved" ItemStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:CheckBox ID="chkApproved" runat="server" Checked='<%# Eval("Approved") %>'
CssClass="bigcheck" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="By">
<ItemTemplate>
<asp:Label ID="lblApBy" runat="server" Text='<%# Eval("ApprovedBy") %>' ></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Approve">
<ItemTemplate>
<asp:Button ID="cmdApprove" runat="server" Text="Approve" CssClass="btn"
onclick="cmdApprove_Click"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<div style="float:right">
<asp:Button ID="cmdApproveAll" runat="server" Text="Approve All" CssClass="btn" />
And our code to load the grid:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid()
End If
End Sub
Sub LoadGrid()
Using conn As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String = "SELECT TOP 6 * from tblHotels"
Using cmdSQL As New SqlCommand(strSQL, conn)
conn.Open()
Dim rstData As New DataTable
rstData.Load(cmdSQL.ExecuteReader)
GridView1.DataSource = rstData
GridView1.DataBind()
End Using
End Using
End Sub
And we now have this:
Ok, so we have a plane jane button on each row. The code to approve a row is this code:
(a simple standard button in the grid view - button click)
Protected Sub cmdApprove_Click(sender As Object, e As EventArgs)
' approve one row
Dim btn As Button = sender
Dim gRow As GridViewRow = btn.NamingContainer
Call ApproveGRow(gRow)
End Sub
Sub ApproveGRow(gRow As GridViewRow)
' set checkbox = checked
Dim ckApprove As CheckBox = gRow.FindControl("chkApproved")
ckApprove.Checked = True
Dim lBy As Label = gRow.FindControl("lblApBy")
lBy.Text = UserInitials
' Get data base pk id
Dim pkID As Integer
pkID = GridView1.DataKeys(gRow.RowIndex).Item("ID")
' Now udpate database
Dim strSQL As String =
"UPDATE tblHotels SET Approved = 1, ApprovedBy = #Initials WHERE ID = #ID"
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand(strSQL, conn)
conn.Open()
cmdSQL.Parameters.Add("#Initials", SqlDbType.NVarChar).Value = UserInitials
cmdSQL.Parameters.Add("#ID", SqlDbType.Int).Value = pkID
cmdSQL.ExecuteNonQuery()
End Using
End Using
End Sub
So, on a button click, we get the current row click, and then call our approve routine that accepts grid ro
So, if I click say on the second row, we see this:
However, what about do the WHOLE gird, with one button, and approve all rows?
Well, the button for the approve all looks like this:
Protected Sub cmdApproveAll_Click(sender As Object, e As EventArgs) Handles cmdApproveAll.Click
For Each gRow In GridView1.Rows
Call ApproveGRow(gRow)
Next
End Sub
And if I click on it, then I get this:
I am new with .net!
I have two gridviews connected to a large database. The first one is returning a list of issues searched by ID while the other is returning the issues searched by subject.
I am trying to get the ID from the gridview returning issues from a select button but when I use selectedRow it doesn't return anything.
I tried multiple methods and this is what I have now. Any Suggestions?
Protected Sub IssuesGV_SelectedIndexChanging(ByVal sender As Object, ByVal e As GridViewSelectEventArgs)
Dim pName As String
pName = IssuesGV.SelectedRow.Cells(0).Text
BindGridComments(pName)
End Sub
Protected Sub IssuesGV_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Attributes("onmouseover") = "this.style.backgroundColor='aquamarine';"
e.Row.Attributes("onmouseout") = "this.style.backgroundColor='white';"
e.Row.ToolTip = "Click last column for selecting this row."
' e.Row.Cells(0).Attributes.Add("onclick", )
End If
End Sub
Protected Sub IssuesGV_RowCommand(sender As Object, e As GridViewCommandEventArgs)
' ' Dim row As GridViewRow = IssuesGV.Rows(rowIndex)
' v = row.Cells(1).Text
'v = IssuesGV.SelectedRow.Cells(0).Text
' TextBox1.Text = v
'TextBox1.Text = v
If (e.CommandName = "Select1") Then
Dim index As Int16
index = Convert.ToInt32(e.CommandArgument)
Dim row As GridViewRow
row = IssuesGV.Rows(index)
Dim item As ListItem
item.Text = Server.HtmlDecode(row.Cells(0).Text)
End If
End Sub
My gridview code is the following (the one where I am using the select button):
<asp:GridView ID="IssuesGV" runat="server" AutoPostBack="true" OnRowCommand ="IssuesGV_RowCommand" OnRowDataBound="IssuesGV_RowDataBound" OnSelectedIndexChanged = "IssuesGV_OnSelectedIndexChanged" SelectedIndexChaning ="IssuesGV_SelectedIndexChanging" AutoGenerateColumns="False" DataKeyNames="number" DataSourceID="IssueDS" EnableModelValidation="True">
<Columns>
<asp:BoundField DataField="number" HeaderText="number" ReadOnly="True" SortExpression="number" />
<asp:BoundField DataField="subject" HeaderText="subject" SortExpression="subject" />
<asp:BoundField DataField="description" HeaderText="description" SortExpression="description" />
<asp:BoundField DataField="created_at" HeaderText="created_at" SortExpression="created_at" />
<asp:BoundField DataField="opener_name" HeaderText="opener_name" SortExpression="opener_name" />
<asp:BoundField DataField="project_name" HeaderText="project_name" SortExpression="project_name" />
<asp:ButtonField Text="Select" CommandName="Select1" ItemStyle-Width="30" ButtonType="Button" HeaderText="Select" ShowHeader="True" SortExpression="number" >
<ItemStyle Width="30px" />
</asp:ButtonField>
</Columns>
</asp:GridView>
The error I am receiving is this one:
System.ArgumentOutOfRangeException HResult=0x80131502
Message=Index was out of range. Must be non-negative and less than the
size of the collection. Parameter name: index Source= StackTrace:
Many Thanks!
Front End:
Your GridView should look like this:
<asp:GridView ID="IssuesGV" runat="server" AutoGenerateColumns="false"
OnSelectedIndexChanged="IssuesGV_OnSelectedIndexChanged">
<Columns>
<asp:BoundField DataField="number" HeaderText="number" />
...Some Other Fields
<asp:ButtonField Text="Select" CommandName="Select" ItemStyle-Width="150" />
</Columns>
</asp:GridView>
Back End:
Then add this code OnSelectedIndexChanged of GridView:
Protected Sub IssuesGV_OnSelectedIndexChanged(sender As Object, e As EventArgs)
'Accessing Selected BoundField Column
Dim number As String = IssuesGV.SelectedRow.Cells(0).Text
label.Text = "<b>Number Value:</b> " & number & " <b>"
End Sub
Ref: See full example here.
Edit
For some reason, if OnSelectedIndexChanged method is not firing then you've just need to add below attribute in your GridView header markup:
AutoGenerateSelectButton="True"
This will create a Select link in your GridView rows, which'll fire the OnSelectedIndexChanged method.
PS: If above all workarounds not works then see this post.
In a nutshell, I am trying to maintain the CheckBox state on a GridView while paging. I am successfully tracking the CheckBox states in the ViewState (using an ArrayList on the row IDs) and I can successfully perform an action on all the checked rows on multiple pages.
However, once I go to a new page and then page back, the checked CheckBoxes are no longer checked (though the row ID still exists in the ArrayList in the ViewState). I have to assume this has something to do with the page life cycle.
I have read the entire ASP.NET Page Life Cycle Overview and tried binding the GridView in the PreRender event (and not binding the GridView at all) which didn't work either. All the examples I found online were loading the GridView DataSource from code behind using a DataTable filled from a SQLDataAdapter. I am using a DataSourceID (from a SQLDataSource) assigned directly to the GridView.
I still can't seem to determine why this is failing. Thanks in advance for your time.
ASPX Page
<asp:SqlDataSource ID="sdsAdminIntakes" runat="server" CancelSelectOnNullParameter="false"
Connectionstring="<%$ ConnectionStrings:MyAppSiteDB %>"
ProviderName="<%$ ConnectionStrings:MyAppSiteDB.ProviderName %>"
SelectCommand="admin_intakes_search"
SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter Name="specialist_id" />
<asp:Parameter Name="caller_name" />
<asp:Parameter Name="case_number" />
<asp:Parameter Name="case_status" />
</SelectParameters>
</asp:SqlDataSource>
<asp:GridView ID="grdAdminIntakes" runat="server"
DataKeyNames="intake_id" DataSourceID="sdsAdminIntakes"
AutoGenerateColumns="False" AllowSorting="True"
AllowPaging="True" PageSize="20">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox runat="server" ID="chkAll" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox runat="server" ID="chkIntake" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="specialist_full_name" HeaderText="Current Specialist"
SortExpression="specialist_full_name" >
</asp:BoundField>
<asp:BoundField DataField="caller_name" HeaderText="Caller"
SortExpression="caller_name" >
</asp:BoundField>
<asp:BoundField DataField="case_number" HeaderText="Case #"
SortExpression="case_number" >
</asp:BoundField>
<asp:BoundField DataField="cmp_status" HeaderText="Case Status"
SortExpression="case_status" ItemStyle-CssClass="case_status" >
</asp:BoundField>
</Columns>
</asp:GridView>
ASPX.VB Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
grdAdminIntakes.DataBind()
End If
End Sub
Private Sub grdAdminIntakes_PageIndexChanging(sender As Object, e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles grdAdminIntakes.PageIndexChanging
GetCheckboxState()
grdAdminIntakes.PageIndex = e.NewPageIndex
grdAdminIntakes.DataBind()
SetCheckboxState()
End Sub
Private Sub GetCheckboxState()
Dim lstArray As ArrayList
If ViewState("SelectedRecords") IsNot Nothing Then
lstArray = DirectCast(ViewState("SelectedRecords"), ArrayList)
Else
lstArray = New ArrayList()
End If
Dim chkAll As CheckBox = DirectCast(grdAdminIntakes.HeaderRow.Cells(0).FindControl("chkAll"), CheckBox)
For i As Integer = 0 To grdAdminIntakes.Rows.Count - 1
If chkAll.Checked Then
If Not lstArray.Contains(grdAdminIntakes.DataKeys(i).Value) Then
lstArray.Add(grdAdminIntakes.DataKeys(i).Value)
End If
Else
Dim chk As CheckBox = DirectCast(grdAdminIntakes.Rows(i).Cells(0).FindControl("chkIntake"), CheckBox)
If chk.Checked Then
If Not lstArray.Contains(grdAdminIntakes.DataKeys(i).Value) Then
lstArray.Add(grdAdminIntakes.DataKeys(i).Value)
End If
Else
If lstArray.Contains(grdAdminIntakes.DataKeys(i).Value) Then
lstArray.Remove(grdAdminIntakes.DataKeys(i).Value)
End If
End If
End If
Next
ViewState("SelectedRecords") = lstArray
End Sub
Private Sub SetCheckboxState()
Dim currentCount As Integer = 0
Dim chkAll As CheckBox = DirectCast(grdAdminIntakes.HeaderRow.Cells(0).FindControl("chkAll"), CheckBox)
chkAll.Checked = True
Dim lstArray As ArrayList = DirectCast(ViewState("SelectedRecords"), ArrayList)
For i As Integer = 0 To grdAdminIntakes.Rows.Count - 1
Dim chk As CheckBox = DirectCast(grdAdminIntakes.Rows(i).Cells(0).FindControl("chkIntake"), CheckBox)
If chk IsNot Nothing Then
chk.Checked = lstArray.Contains(grdAdminIntakes.DataKeys(i).Value)
If Not chk.Checked Then
chkAll.Checked = False
Else
currentCount += 1
End If
End If
Next
End Sub
After several more hours of research, I was finally able to get this working by moving the SetCheckboxState() out of the grdAdminIntakes_PageIndexChanging event and into the grdAdminIntakes_DataBound event.
Suppose I have two .aspx pages and a connection the the sql server database engine.
The first page, let's call it playground.aspx, I'm having a set of databound which using the stored procedure for SELECT function (using dataset for it).
Now in the second page, let's call it link.aspx, there are two textbox, suppose there are multiple data in the playground.aspx page and I want to retrieve Entity Code and Username data (from the playground.aspx's databound) and show it in the link.aspx's textbox.
How can I do that?
I was told to create some function, but I never dealt with a databound before, only with TextBox and Label, it really confused me.
Any help's appreciated, thank you.
EDIT (Here's the databound code)
<asp:Panel ID="PanelDGV" runat="server" Height="100%" ScrollBars="None" Width="100%">
<asp:GridView ID="DGV" runat="server" AutoGenerateColumns="False" GridLines="None"
AllowPaging="true" PageSize="2" CssClass="mGrid" PagerStyle-CssClass="pgr" AlternatingRowStyle-CssClass="alt">
<Columns>
<asp:BoundField DataField="EntityCode" HeaderText="Entity Code" />
<asp:BoundField DataField="UserName" HeaderText="Username" />
<asp:BoundField DataField="DivCode" HeaderText="Div Code" />
<asp:BoundField DataField="GroupCode" HeaderText="Group Code" />
<asp:BoundField DataField="CreatedBy" HeaderText="Created By" />
<asp:BoundField DataField="CreatedOn" HeaderText="Created On" />
<asp:BoundField DataField="ModifiedBy" HeaderText="Modified By" />
<asp:BoundField DataField="ModifiedOn" HeaderText="Modified On" />
<asp:ButtonField ButtonType="Image" ImageUrl="../Support/Image/Edit.png" ItemStyle-HorizontalAlign="Center"
CommandName="CmdEdit" HeaderText="Edit">
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:ButtonField>
</Columns>
<PagerStyle CssClass="pgr"></PagerStyle>
<AlternatingRowStyle CssClass="alt"></AlternatingRowStyle>
</asp:GridView>
</asp:Panel>
I just solved the problem, here's the code
For link.vb
Public Function F01_sysUser_Select(ByVal EntityCode As String, ByVal Username As String) As ProcessResult
Try
Dim SqlCmd As New SqlCommand()
SqlCmd.Connection = New SqlConnection(CF.CfgConnectionString)
SqlCmd.CommandType = CommandType.StoredProcedure
SqlCmd.CommandTimeout = CF.CfgCommandTimeout
SqlCmd.CommandText = "sysUser_SelectByID"
SqlCmd.Parameters.Add("#EntityCode", SqlDbType.VarChar) : SqlCmd.Parameters(0).Value = EntityCode
SqlCmd.Connection.Open()
Dim Dr As SqlDataReader = SqlCmd.ExecuteReader(CommandBehavior.CloseConnection)
F01_Dt_sysUser.Clear()
F01_Dt_sysUser.Load(Dr)
If F01_Dt_sysUser.Rows.Count > 0 Then
Dr.Close()
Dr = Nothing
SqlCmd.Dispose()
Return ProcessResult.SuccessWithResult
Else
Dr.Close()
Dr = Nothing
SqlCmd.Dispose()
Return ProcessResult.SuccessWithNoResult
End If
Catch ex As Exception
InsertErrorLog("PlaygroundLink.F01_sysUser_Select", ex.Message)
ExMessage = ex.Message
Return ProcessResult.Failed
End Try
End Function
and in the link.aspx.vb:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim QSEntityCode As String
Dim QSUserName As String
QSEntityCode = Request.QueryString("QSEC").ToString
QSUserName = Request.QueryString("QSUN").ToString
Dim Bl As New PlaygroundLink
If Bl.F01_sysUser_Select(QSEntityCode, QSUserName) = CF.ProcessResult.SuccessWithResult Then
TbEntityCode.Text = QSEntityCode
TbUsername.Text = QSUserName
Else
' LblMessage.Text = Bl.ExMessage
End If
End Sub
lastly in playground.aspx.vb:
Private Sub DGV_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles DGV.RowCommand
If e.CommandName = "CmdEdit" Then
Dim QSEntityCode As String
Dim QSUserName As String
Dim idx As Integer = Convert.ToInt32(e.CommandArgument)
Dim row As GridViewRow = DGV.Rows(idx)
QSEntityCode = row.Cells(0).Text
QSUserName = row.Cells(1).Text
Response.Redirect(RR.PlaygroundLink & "?QSEC=" & QSEntityCode & "&QSUN=" & QSUserName)
End If
End Sub
After that, I get what I want, displaying the result in the link.aspx textbox, cheers! :)
I'm currently working on some code which is taking care of sorting and paging data in a gridview. I'm now trying to implement sorting arrow (up/down arrows next to column headers) but I have no success. The code to implement the sorting arrows is located in the *GridView1_RowCreated* sub routine. Right now, when I run the code, I don't see the sorting arrows at all. The problematic line is the following one: "If tblAdministrators.SortExpression = lnk.CommandArgument Then" I can't figure out what's wrong with that line. It's always False therefore the arrows don't show up.
Private Function GetData(sort As SortDirection) As Data.DataView
Dim connection As OracleDBConnect = DAL.GetOracleDBConnection()
Dim request As OracleDBRequest = Nothing
Dim result As OracleDBResult = Nothing
Dim trace As OracleDBChronoTrace = Nothing
Dim status As DBStatus
Dim sb As New StringBuilder
Dim dv As DataView
With sb
.Append("SELECT * FROM USERS")
End With
request = New OracleDBRequest(sb.ToString, CommandType.Text)
status = connection.Execute(request, result, trace)
dv = New DataView(result.DataSet.Tables(0))
If (ViewState("sortExp") IsNot Nothing) Then
dv = New Data.DataView(result.DataSet.Tables(0))
If (GridViewSortDirection = SortDirection.Ascending) Then
GridViewSortDirection = SortDirection.Descending
dv.Sort = CType(ViewState("sortExp").ToString() & DESCENDING, String)
Else
GridViewSortDirection = SortDirection.Ascending
dv.Sort = CType(ViewState("sortExp").ToString() & ASCENDING, String)
End If
Else
dv = result.DataSet.Tables(0).DefaultView
End If
Return dv
End Function
Public Property GridViewSortDirection() As SortDirection
Get
If ViewState("sortDir") Is Nothing Then
ViewState("sortDir") = SortDirection.Ascending
End If
Return CType(ViewState("sortDir"), SortDirection)
End Get
Set(ByVal value As SortDirection)
ViewState("sortDir") = value
End Set
End Property
Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles tblAdministrators.PageIndexChanging
tblAdministrators.PageIndex = e.NewPageIndex
GridViewSortDirection = If(GridViewSortDirection = SortDirection.Descending, SortDirection.Ascending, SortDirection.Descending)
tblAdministrators.DataSource = GetData(GridViewSortDirection)
tblAdministrators.DataBind()
End Sub
Protected Sub GridView1_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles tblAdministrators.Sorting
ViewState("sortExp") = e.SortExpression
tblAdministrators.DataSource = GetData(GridViewSortDirection)
tblAdministrators.DataBind()
End Sub
Protected Sub GridView1_RowCreated(sender As Object, e As GridViewRowEventArgs) Handles tblAdministrators.RowCreated
If e.Row.RowType = DataControlRowType.Header Then
For Each tc As TableCell In e.Row.Cells
If tc.HasControls() Then
Dim lnk As LinkButton = DirectCast(tc.Controls(0), LinkButton)
If lnk IsNot Nothing Then
Dim img As New System.Web.UI.WebControls.Image()
img.ImageUrl = "/images/" & (If(GridViewSortDirection = SortDirection.Ascending, "asc", "desc")) & ".gif"
If tblAdministrators.SortExpression = lnk.CommandArgument Then
tc.Controls.Add(New LiteralControl(" "))
tc.Controls.Add(img)
End If
End If
End If
Next
End If
End Sub
ASPX code:
<asp:GridView ID="tblAdministrators" runat="server" AutoGenerateColumns="false" EmptyDataText="No records found" PageSize="25" AllowPaging="True" AllowSorting="True" OnRowCreated="GridView1_RowCreated">
<Columns>
<asp:BoundField HeaderText="Name" DataField="Name" SortExpression="NAME"></asp:BoundField>
</Columns>
<Columns>
<asp:BoundField HeaderText="City" DataField="City" SortExpression="CITY"></asp:BoundField>
</Columns>
</asp:GridView>
Take a look at my sample:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="CustomerId"
DataSourceID="SqlDataSource1">
<SortedAscendingHeaderStyle CssClass="sortasc" />
<SortedDescendingHeaderStyle CssClass="sortdesc" />
<Columns>
<asp:CommandField ShowSelectButton="True" />
<asp:BoundField DataField="CustomerId" HeaderText="CustomerId"
InsertVisible="False" ReadOnly="True" SortExpression="CustomerId" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="IdNumber" HeaderText="IdNumber"
SortExpression="IdNumber" />
</Columns>
</asp:GridView>
Pay attention on SortedAscendingHeaderStyle and SortedDescendingHeaderStyle. Just create apropriate css classes with background image (arrow up and arrow down) and you are done.
In Order to add a sorting arrow in a Data Grid on a VB.net Windows Form, you don't even have to write any code
On form in Design Mode - select the grid you are working with, right click go to properties, set Selection Mode = Cell Select
On form in Design Mode - click the arrow on the grid on the right up, to edit column properties, select edit or add columns, set SortMode = Automatic
If you have code for your cell content (say you want user to open another form while clicking on any row in the data grid) then use CellDoubleClick property to handle the event. If the you have used single click then it will sort the header and also open the form for the given cell
Private Sub _CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles DGAcctGrpList.CellDoubleClick