Update Hyperlink In Gridview not working - asp.net

Gridview is not working when user click on the link. User is supposed to be directed to another page when clicked on the link and on the second page, there is a text box that will allow user to update.
this is my code for grid view:
<asp:BoundField DataField = "status" HeaderText = "Status" HtmlEncode = "true" ItemStyle-Width="150px" >
<ItemStyle Width="50px" />
</asp:BoundField>
<asp:ButtonField ButtonType="Link" Text="Click" CommandName="Select" HeaderText="Details" />
<asp:ButtonField HeaderText="Update" Text="update?" CommandName="GridView1_RowUpdated" />
code behind:
Protected Sub GridView1_RowUpdated(sender As Object, e As GridViewUpdatedEventArgs)
Dim cr_number As String = GridView1.SelectedRow.Cells(0).Text
Response.Redirect("upddetail.aspx?id=" + cr_number)
End Sub

since you are set the CommandName as GridView1_RowUpdated you can use GridView1_RowCommand event as below
Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As GridViewCommandEventArgs)
If e.CommandName = "GridView1_RowUpdated" Then
Dim index As Integer = Convert.ToInt32(e.CommandArgument)
Dim cr_number As String = GridView1.Rows(index).Cells(0).Text
Response.Redirect("upddetail.aspx?id=" + cr_number)
End If
End Sub
in your aspx page set onrowcommand as below
<asp:gridview id="GridView" onrowcommand="GridView1_RowCommand"
instead of all above you can use hyperlinkfield
<asp:hyperlinkfield text="Update?"
datanavigateurlfields="Id"
datanavigateurlformatstring="~\upddetail.aspx?id={0}"
headertext="Update"
target="_blank" />

You are using ButtonField not an actual hyperlink. When user clicks on this there will be a postback to your original page and it will not navigate to another page. Try using HyperLink.

Related

How do I enable row selection in an ASP GridView without disabling EnableEventValidation?

I have an ASPX page that includes a GridView. I want to be able to select a row from the grid, and populate another section of the page based on the selected row. It works if I have EnableEventValidation="false" in the <%# Page %> line, but I have been told that I cannot use that because of a security concern. When I don't include it, selecting a grid row throws an "Invalid postback or callback argument" exception.
How can I implement row selection without disabling event validation?
Here is my code:
ASPX page:
<asp:GridView runat="server" ID="TheGrid" AutoGenerateColumns="false" DataKeyNames="id" EmptyDataText="No Data Found" AllowSorting="true">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="First Name" ReadOnly="true" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" ReadOnly="true" SortExpression="LastName" />
<asp:BoundField DataField="Email" HeaderText="Email" ReadOnly="true" SortExpression="Email" />
</Columns>
</asp:GridView>
ASPX.VB code:
Protected Sub TheGrid_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles TheGrid.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Attributes("onclick") = Page.ClientScript.GetPostBackClientHyperlink(TheGrid, "Select$" & e.Row.RowIndex)
e.Row.Attributes("style") = "cursor:pointer"
End If
End Sub
Protected Overrides Sub Render(writer As HtmlTextWriter)
ClientScript.RegisterForEventValidation("TheGrid")
MyBase.Render(writer)
End Sub
Note that when I select a row, the exception is thrown somewhere between Page_Load and Render.
Ok, lets wire up the GV two ways.
First way, drop in a plane jane button for the row click
(we will delete the button and add row click in 2nd example).
so, say this simple GV
<div id="MyGridArea" runat="server" clientidmode="static">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID"
CssClass="table table-hover" Width="60em" GridLines="None"
ShowHeaderWhenEmpty="true">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="cmdEdit" runat="server" Text="Edit" CssClass="btn myshadow"
OnClick="cmdEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
Note how we just dropped in a plane jane button.
And our code to fill out above is this:
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()
Dim strSQL = "SELECT * FROM tblHotelsA ORDER BY HotelName"
GridView1.DataSource = Myrst(strSQL)
GridView1.DataBind()
End Sub
And now we have this:
Ok, so next part is to drop in a "div" area that allows edit of one row.
So, again, quite much plan jane controls.
And we can "hide" grid when we edit, and show edit area div.
But, I often use jQuery.UI. Really amounts to much the same code as simple hide/show, but this way jQuery.UI turns that SAME div into a nice pop up area.
So, that div area might look like this:
<div id="EditRecord" runat="server" style="float: left; display: none" clientidmode="Static">
<br />
<div style="float: left" class="iForm">
<label>HotelName</label>
<asp:TextBox ID="txtHotel" runat="server" f="HotelName" Width="280">
</asp:TextBox>
<br />
<label>First Name</label>
<asp:TextBox ID="tFN" runat="server" f="FirstName" Width="140"></asp:TextBox>
<br />
<label>Last Name</label>
<asp:TextBox ID="tLN" runat="server" f="LastName" Width="140"></asp:TextBox>
<br />
<label>City</label>
<asp:TextBox ID="tCity" runat="server" f="City" Width="140"></asp:TextBox>
<br />
<label>Province</label><asp:TextBox ID="tProvince" runat="server" f="Province" Width="75"></asp:TextBox>
</div>
etc. etc. etc.
so, now lets wire up the button above.
The button will simple:
Get current grid row
Get PK id
Load up div and display.
So, that code is this:
Protected Sub cmdEdit_Click(sender As Object, e As EventArgs)
Dim btn As Button = sender
Dim gRow As GridViewRow = btn.NamingContainer
EditRow(gRow.RowIndex)
End Sub
Sub EditRow(rowNum As Integer)
Dim intPK As Integer = GridView1.DataKeys(rowNum).Item("ID")
Dim strSQL As String = "SELECT * FROM tblHotelsA WHERE ID = " & intPK
Dim rstData As DataTable = Myrst(strSQL)
' load up our edit div
fLoader(Me.EditRecord, rstData.Rows(0))
ViewState("PK") = intPK
ScriptManager.RegisterStartupScript(Me.Page, Page.GetType, "mypopedit", "popedit()", True)
End Sub
As noted, I added a popup from jQuery.UI, but we could just use plain jane "div" and hide/show the grid and show the edit area (or like you have, have that edit area in full view).
(fLoader is a routine I built some time ago - I like everyone became VERY tired of typing code over and over to fill out text boxes etc., so for any text box etc., I use a "made up" attribute called f="Data base column name", and that routine just loops the controls on the form and fills them out. No different than hand coding simple assignments to controls, but with this code I can re-use it over and over.
So, we now see, get this:
Ok, so the only next goal is to add a row click
(and not use that edit button).
So, then all we need is a routine that will get the current row index, and call our edit row routine we have above.
So, we use row data bound, and add that click event that way.
but, do note how the above button click gets the current row. That nice short code works for repeaters, listview etc. (we used naming container).
But, if you want a row click in place of that button?
Then on row data bound, add this code:
Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Attributes.Add("onclick",
"__doPostBack('myrowedit'," & e.Row.RowIndex & ")")
End If
End Sub
And in our page load event, we have this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid()
Else
If Request("__EVENTTARGET") = "myrowedit" Then
EditRow(Request("__EVENTARGUMENT"))
End If
End If
End Sub
And a handy dandy routine that returns a table based on SQL I used above was this:
Public Function Myrst(strSQL As String) As DataTable
Dim rstData As New DataTable
Using mycon As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand(strSQL, mycon)
mycon.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
End Using
Return rstData
End Function
So, all in all, not a lot of code.
You can try the above working example here:
http://www.kallal.ca/Website11/WebForm2

.NET - SelectedRow not returning any value

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.

Get row values programmatically from gridview

I have a GridView Control and one button:
<asp:GridView ID="grdView" runat ="server" AutoGenerateColumns ="false" >
<Columns>
<asp:TemplateField HeaderText ="Balance">
<ItemTemplate>
<%#Eval("Balance") %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button runat="server" ID ="btn" Text ="test"/>
Then on load page, I populate the gridView with a list of agreements. on that list there are one field called "Balance":
Private Sub form1_Load(sender As Object, e As EventArgs) Handles form1.Load
Dim agreementManager As AgreementManager = New AgreementManager()
Dim lstBalances As List(Of Agreement) = agreementManager.GetByClientId(2)
grdView.DataSource = lstBalances
grdView.DataBind()
End Sub
Then it display me this after loaded:
I am trying to read programmatically one specific balance with:
Private Sub btn_Click(sender As Object, e As EventArgs) Handles btn.Click
Dim value As String = grdView.Rows(1).Cells(0).Text
End Sub
But the "value" is empty.
What I am doing wrong?
I am working on mock a system that uses this way to read the values from a grid view, and this code works fine:
Dim balance As Decimal =
CType(grdApplyTransactionsAgreements.Rows(idx).Cells(BALANCE_CELLID).Text, Decimal)
this code is inside a button too.
Thanks!!
The .Text property can only be read after DataBinding from AutoGenerated columns and BoundField columns. But even if you could I would not recommend it since all you are getting is a string, not the original datatype.
Better read the values from the source lstBalances.
I bumped into an answer, I need to use BondField Control instead Template Field, now everything runs fine.
<asp:GridView ID="grdView" runat ="server" AutoGenerateColumns ="false" >
<Columns>
<asp:BoundField DataField ="Balance" HeaderText ="Balance"/>
</Columns>
</asp:GridView>

In ASP.NET, how do I change the visibility of a button in the same column of a gridview itemtemplate when the other button is clicked?

I have the following gridview:
<asp:GridView ID="gridOpenMECs" runat="server">
<Columns>
<ItemTemplate>
<asp:ImageButton ID="btnShow" runat="server" ImageUrl="xxx.png"
OnClick="btnShow_OnClick" />
<asp:ImageButton ID="btnHidden" runat="server"
ImageUrl="yyy.png" Visible="false" />
</ItemTemplate>
</Columns>
</asp:GridView>
When button1's onclick serverside event is fired I want to obtain a handle on button2 so that I may change its Visible attribute to True.
Protected Sub btnShow_OnClick(ByVal sender As Object, ByVal e As ImageClickEventArgs)
Dim btn as ImageButton = CTYPE(sender, ImageButton) 'get the sending button handle
'' what next to make btnHidden visible?
End Sub
How can I accomplish this? Thank you.
Sorry, C# speak ...
GridViewRow whichrow = (GridViewRow)btn.NamingContainer;
ImageButton btnHidden = (ImageButton)whichrow.FindControl("btnHidden")

Passing a values from Datatable to UserControl Property

I am new to programming. I'm creating a program which adds a UserControl to a Gridview template dynamically and I want to pass a value from datatable to a property of a UserControl. The TemplateField in Gridview is already preloaded with 1 user control and if I clicked on a button, this will add a new UserControl with a numbering.
Here is the code from the page on FormLoad event.
Dim dtSESRatings As New DataTable
dtSESRatings.Columns.Add("IncrementNumber")
dtSESRatings.Rows.Add("1")
ViewState("dtSESRatings") = dtSESRatings
gvSesRating.DataSource = dtSESRatings
gvSesRating.DataBind()
And I want to add the row to the Numbering label in the user control which is the IncrementNumber Property set on SESRatings.ascx.
This is the asp code:
<asp:GridView ID="gvSesRating" runat="server" Width="100%" ShowHeader="false" GridLines="None"
AutoGenerateColumns="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<ses:SESRatings runat="server" ID="ses1" IncrementNumber="1" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
After FormLoad, upon clicking on a button "ADD NEW RATING", it is supposed to create a new user control in the gridview and the code is here:
Protected Sub btnAddRating_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnAddRating.Click
Dim dt As DataTable = ViewState("dtSESRatings")
Dim dtCnt As Integer = dt.Rows.Count
dtCnt += 1
dt.Rows.Add(dtCnt)
ViewState("dtSESRatings") = dt
gvSesRating.DataSource = dt
gvSesRating.DataBind()
dt = Nothing
End Sub
I want that the user control that will be added in the GridView will get the dtCnt and pass it to the IncrementNumber Property of the User Control. How can I do that? Please help. Thanks.
you must use Eval tags in your gridview control:
<ses:SESRatings runat="server" ID="ses1" IncrementNumber='<%# Eval("IncrementNumber") %>' />

Resources