Add Row Click Event to Asp.Net GridView Rows - asp.net

Is there a way to add a RowClick Event to Gridview Rows without adding a button to each one? I want to be able to click anywhere in the row and raise the SelectedIndexChanged event.
I tried the following but I need to add pages enableEventValidation="true" and I really don't want to do that.
Private Sub GridView1_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
Try
Select Case e.Row.RowType
Case DataControlRowType.DataRow
e.Row.Attributes.Add("onclick", Page.ClientScript.GetPostBackClientHyperlink(GridView1, "Select$" & e.Row.RowIndex))
End Select
Catch ex As Exception
End Try
End Sub
The RowCommands wont work either because you have to have a button.

You did step 1 of 2. First part was registering the onclick in the RowDataBound. Now you need to handle the SelectedIndexChanged event. I'm not a VB.Net guy, so I'm not 100% sure on how to wire it up. The event handler will look like this, though:
Private Sub GridView1_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles GridView1.SelectedIndexChanged
' Do stuff here.
End Sub
Also, change your onclick wire up code to use Page.ClientScript.GetPostBackEventReference instead of Page.ClientScript.GetPostBackClientHyperlink.
Here is some example markup:
<asp:GridView ID="GridView1"
runat="server"
Width="665px"
OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
<HeaderStyle BackColor="#0033CC" />
<Columns>
<asp:CommandField ShowSelectButton="True" />
</Columns>
</asp:GridView>

Related

Get Button Id Sender In Grid Batch update Dev Express vb.net

I have a method "Grid Batch Update", in this case, i want get an id from button clicked in this method
Private Sub grid_BatchUpdate(ByVal sender As Object, ByVal e As DevExpress.Web.Data.ASPxDataBatchUpdateEventArgs) Handles grid.BatchUpdate
'My Code
End Sub
I have tried to search but not found the answer
Ok, then as a general rule, you can use "sender".
Protected Sub Button1_Click1(sender As Object, e As EventArgs) Handles Button1.Click
Dim btn As Button = sender
Debug.Print("id of button is " & btn.ID)
End Sub
However, do note if you going to have say several buttions use the SAME event?
Then you should remove the handles from above. And then you "must" then set the on-click event.
So, above becomes:
Protected Sub Button1_Click1(sender As Object, e As EventArgs)
Dim btn As Button = sender
Debug.Print("id of button is " & btn.ID)
End Sub
And I might then say have two buttons use the same click event. eg this:
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click1" />
<br />
<asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button1_Click1" />
So, if you double click on a button from the web forms designer, it will NOT put in a OnClick tag, but uses the "handles button one in code behind.
Either way is fine - but you don't need (nor want) the "handles" tied to one button on the code behind - so use markup OnClick="Button1_Click1"
In above, then clicking on either button would result in this:

How to dynamically add controls and preserve Viewstate?

I'm attempting to use Controls.AddAt(), but it apparently breaks controls at later indexes:
Here's my minimal example:
Aspx put in a form:
<asp:DropDownList runat="server" ID="ddl" />
<asp:Button Text="text" runat="server" OnClick="Unnamed2_Click" />
Code Behind:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
ddl.Items.Add("Click the button")
'Controls.Add(New HyperLink) 'Works fine, but is put at end of collection.
'Controls.AddAt(2 ,New HyperLink) 'Is also safe but I wanted the control first
Controls.AddAt(0, New HyperLink) 'ddl loses it's item after postback
End If
End Sub
On the first postback of the page after calling AddAt, the DropDownList loses it's item. It doesn't matter what kind of control I add even HTMLControls. Viewstate is not disabled.
How do I dynamically add controls without breaking others?
If you used a PlaceHolder to add your HyperLink into, it would not mess up the rest of the page:
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
<asp:DropDownList ID="ddl" EnableViewState="true" runat="server" />
<asp:Button ID="bn1" Text="text" OnClick="Unnamed2_Click" runat="server" />
With code like
Protected Sub Unnamed2_Click(sender As Object, e As EventArgs) Handles bn1.Click
Dim newItem = "Click the button" & DateTime.Now.ToString("HH:mm:ss")
ddl.Items.Add(newItem)
ddl.SelectedIndex = ddl.Items.Count - 1
PlaceHolder1.Controls.Add(New HyperLink With {.ID = "hyp", .Text = "Hyperlink here"})
End Sub
And always give your asp:Controls an ID if they take one.

Checkbox in TemplateField ItemTmplate event won't fire

Ok I am using a column with check box to be able to select my data row from a GridView. But The OnCheckChanged event won't fire. I have tried reading articles to make it work and copy code exactly and it just won't fire. I am using vb.net and asp.net
<asp:GridView ID="locationDetailGrid" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate >
<asp:CheckBox ID="locationSelection" AutoPostBack="true"
runat="server" OnCheckedChanged="CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Protected Sub CheckedChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim checkbox As CheckBox = DirectCast(sender, CheckBox)
Dim row As GridViewRow = DirectCast(checkbox.NamingContainer, GridViewRow)
Response.Write(row.Cells(0).Text)
End Sub
Probably because you're databinding the GridView also on postbacks. Add an If Not Page.IsPostback into Page_Load around your databinding stuff of the GridView.
If you rebind the GridView on postbacks, you're preventing events from triggering.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
BindGridToDataSourceAndDataBind()
End If
End Sub

GridView Row Redirect to Pre-filled DetailsView on Button Click

Background:
I have a GridView which gets populated from an SqlDataSource via DataSourceID. The rows show some summary data from an SQL View. Upon clicking a row, I would like to take my user to another page with a DetailsView control which gets populated with the full set of values from the DB related to the row clicked. My user should be able to edit the data, download files associated with the record, and create a new record of a different type based on said data.
Error:
All examples that I've found for Clickable GridView rows end up with some variation of the error Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%# Page EnableEventValidation="true" %> in a page.
Naturally, I do not want to expose my site to vulnerabilities by disabling event validation. I need to be able to grab the Primary key of the clicked row's associated record and perform operations on that data on a subsequent page, probably via a DetailsView. I suspect my errors are a result of my setup, which is why I included those details.
My Questions Are:
How do I capture the Primary Key of clicked row?
How do I, onclick, forward to a "details" page with a pre-filled form containing data from the row record that was clicked?
HERE'S THE COMPLETE SOLUTION
**thanks again to Icarus' help
'Fetch the DataKey ("ID"), seems to work
Protected Sub RowBind(ByVal sender As Object, ByVal e As GridViewRowEventArgs) _
Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim datakey As String = GridView1.DataKeys(e.Row.RowIndex).Value.ToString()
End If
End Sub
'Handle button click
Protected Sub RowClick(ByVal sender As Object, ByVal e As GridViewCommandEventArgs) _
Handles GridView1.RowCommand
If e.CommandName = "Select" Then
'Add to session variable; translate the index of clicked to Primary Key
Session.Add("DetailsKey", GridView1.DataKeys(e.CommandArgument).Value.ToString)
Response.Redirect("details.aspx")
End If
End Sub
And My Markup
<asp:GridView ID="GridView1" runat="server" DataSourceID="GridView1SDS"
DataKeyNames="ID" AllowPaging="True" AllowSorting="True">
'<!-- Styling -->
<Columns>
<asp:ButtonField ButtonType="Button" Text="Details" CommandName="Select" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="GridView1SDS" runat="server"
ConnectionString="<%$ ConnectionStrings:dbConnectionString %>"
SelectCommand="select * from viewRequestQueue">'<!-- An SQL View -->
</asp:SqlDataSource>
Forwarded Page VB & Markup
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
GridView2SDS.SelectCommand = "select * from viewRequestQueue where ID = " _
+ Session.Item("DetailsKey").ToString
End If
End Sub
<asp:DetailsView ID="GridView2" runat="server" DataSourceID="GridView2SDS">
'<!-- Styling -->
</asp:DetailsView>
<asp:SqlDataSource ID="GridView2SDS" runat="server"
ConnectionString="<%$ ConnectionStrings:dbConnectionString %>">
</asp:SqlDataSource>
Also, please note that if the SelectCommand for your DataSource is handled in the codebehind, that means the DataBind will overwrite your <Columns> in the markup. To get around this, you should define the columns in the code behind before the DataBind. So say I wanted to add another ButtonField column to my forwarded page (notice the SelectCommand is not provided in the markup), I added the following before the setting the SelectCommand and doing the DataBind:
Dim id As New ButtonField()
id.ButtonType = ButtonType.Button
id.Text = "Load"
id.CommandName = "Select"
PubDetails.Columns.Add(id)
You need to declare the KeyNames of the items you are binding on your markup. For example:
<asp:GridView id="grid" runat="Server" DataSourceID="YourSQLDataSource" DataKeyNames="ID,Name" />
In your case, you seemed to be handling the OnRowDataBound event. You can do this to grab the key inside RowBound:
If e.Row.RowType = DataControlRowType.DataRow Then
Dim datakey As String = GridView1.DataKeys(e.Row.RowIndex).Value.ToString() 'get the datakey
End If
Your second question is difficult to answer because you did not specify how you want the user to be redirected, if from the client side using Javascript or from the Server side. You also did not specify how do you expect to populate the details on the Details page. Do you expect to read a parameter from the URL and use it to get the record details from the database?

Button Click and LinkButton Click

I am having a strange day! I am trying to access values inside the Datagrid control. There are textboxes in each row of the Datagrid control. If I use a asp.net button control outside the datagrid control I can access all the values. But if I use LinkButton outside the datagrid control then I cannot access any value.
I have to use LinkButton.
UPDATE 1: Code
//This works
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim indexes() As Integer = dgReceipts.SelectedIndexNumbers
End Sub
//This does not work and I get 0 items in the SelectedIndexNumbers
Protected Sub LinkButtonUpdateReceipts_Click(sender As Object, e As EventArgs) Handles LinkButtonUpdateReceipts.Click
Dim indexes() As Integer = dgReceipts.SelectedIndexNumbers
End Sub
<asp:Button ID="Button1" runat="server" Text="Button" />
<c1:LinkButton ID="LinkButtonUpdateReceipts" runat="server" Text="Update Totals" Icon="images/go-blue-right.gif"></c1:LinkButton>
I'm suprised that either of those work. You do not appear to have an OnClick event for either of those buttons. At a minimum I would add an OnClick event to your LinkButton that fires LinkButtonUpdateReceipts_Click.
Also, why aren't you just using <asp:LinkButton? what is <c1:LinkButton?

Resources