I am dynamically adding a link button to every cell in a gridview. Adding the button works however the firing of the even handler doesn't. i need the linkbutton to call a function and pass some data for processing. My code is below. I have found solutions from the site that have gotten me this far.
At the moment the gridview loads the cells with buttons in blue. when you click them they go back to plain text and no function is called.
Private Sub gv_datasource_options_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gv_datasource_options.RowDataBound
Try
If e.Row.RowType = DataControlRowType.DataRow Then
For Each c As TableCell In e.Row.Cells
If Len(c.Text) > 0 And c.Text <> " " Then
Dim v_lb As New LinkButton()
v_lb.Text = c.Text
AddHandler v_lb.Click, AddressOf add_datasource
v_lb.Attributes.Add("AutoPostback", "True")
v_lb.Attributes.Add("runat", "Server")
v_lb.Attributes.Add("AutoEventWireup", "True")
v_lb.CommandName = "NumClick"
v_lb.CommandArgument = e.Row.Cells(0).ToString & "|" & gv_datasource_options.HeaderRow.Cells(e.Row.Cells.GetCellIndex(c)).Text
c.Controls.Add(v_lb)
Dim sm As ScriptManager = ScriptManager.GetCurrent(Me)
sm.RegisterAsyncPostBackControl(v_lb)
End If
Next
End If
Catch ex As Exception
cl_Error.cl_Erorr.LogError(ex, txt_userid.Value, ex.ToString)
End Try
End Sub
Private Sub add_datasource(sender As Object, e As CommandEventArgs)
Try
hf_datasource_id.Value = Left(e.CommandArgument.ToString(), (Len(e.CommandArgument.ToString) - InStr(e.CommandArgument.ToString, "|")))
hf_datasource_column.Value = Left(e.CommandArgument.ToString(), (Len(e.CommandArgument.ToString) - InStr(e.CommandArgument.ToString, "|")))
hf_datasource_tableid.Value = tv_content.SelectedValue
p_datasource.Visible = False
Catch ex As Exception
cl_Error.cl_Erorr.LogError(ex, txt_userid.Value, ex.ToString)
End Try
End Sub
Rather than adding Event ("add_datasource") to Linkbutton, trying using GridView's RowCommand Event. You will surely be able to fetch the event bubbled by linkbutton on Gridview's Row Command Event (along with the commandname and commandarguments)
Related
I'm creating dynamic LinkButton where I assign to it dynamically an ID now I would be able to write an onClick function where I get that ID but after trying to make something like that I had no result:
table.Append("<td><asp:LinkButton runat=""server"" class=""edit btn btn-sm btn-default"" ID=" & reader.GetString("id") & " OnClient=""Delete_User""><i class=""fa fa-trash-o"" aria-hidden=""true""></asp:LinkButton></i></a>")
While here is VB.NET code
Sub Delete_User(sender As Object, e As EventArgs)
Dim clickedBtn As LinkButton = CType(sender, LinkButton)
MsgBox(clickedBtn.ID)
End Sub
The LinkButton is a server control and you cannot render it with same way as you render plain HTML tags from code-behind, it will not work as expected. You need to provide HtmlTableCell instance and bind LinkButton control from there, assumed table is defined as HtmlTable:
' this is just a sample event
Protected Sub SomeEventHandler(sender As Object, e As EventArgs)
Dim table As HtmlTable = New HtmlTable()
Dim row As HtmlTableRow = New HtmlTableRow()
' set the data reader from database here
Dim cell As HtmlTableCell = New HtmlTableCell()
Dim linkbtn As LinkButton = New LinkButton()
linkbtn.ID = reader.GetString("id") ' setting control ID
linkbtn.Text = "Delete User" ' setting link text
linkbtn.CssClass = "edit btn btn-sm btn-default"
AddHandler lnkbutton.Click, AddressOf Delete_User ' assign event handler
' add the control to table cell ('td' element)
cell.Controls.Add(linkbtn)
row.Cells.Add(cell)
table.Rows.Add(row)
' other stuff
End Sub
Note that you should provide server-side click event with Click property which associated with OnClick event, not OnClient nor OnClientClick.
Additional note:
MsgBox cannot be used in ASP.NET because it belongs to WinForms, you need to provide JS alert() function to show message box with RegisterStartupScript or RegisterClientScriptBlock:
Sub Delete_User(sender As Object, e As EventArgs)
Dim clickedBtn As LinkButton = CType(sender, LinkButton)
Dim message As String = "alert('" & clickedBtn.ID & "');"
Page.ClientScript.RegisterClientScriptBlock(Me.[GetType](), "MsgBox", message, True)
End Sub
Related issues:
How to add linkbutton control to table cell dynamically
Creating a link button programmatically
How to add dynamically created buttons to a dynamically created table?
I have an ASP.NET DataGrid that returns three clickable columns at the end. When running SelectedIndexChanged how can I return the value of the item that was clicked?
Thanks
Private Sub DG_SelectedIndexChanged(sender As Object, e As EventArgs)
Try
Dim DG As GridView = CType(sender, GridView)
Dim vID As Integer = DG.SelectedRow.Cells(0).Text
'Need to determine which item was clicked here
Catch ex As Exception
End Try
End Sub
In the end I found the only way was to add an onclick event to the LinkButton
AG_Link.Text = "View Agenda"
AG_Link.Attributes.Add("onclick", "returnDocumentType('Agenda');")
Add some JavaScript to update a hidden textbox, then pick up the result
Private Sub DG_SelectedIndexChanged(sender As Object, e As EventArgs)
Try
Dim DG As GridView = CType(sender, GridView)
Dim vID As Integer = DG.SelectedRow.Cells(0).Text
Dim DocumentType As String = DocumentTypeTB.Text
Catch ex As Exception
End Try
End Sub
Bit of a long way round, but it works :-)
Developed a slightly dynamic page that builds a Question and Answer page based on information from a database. Everything works great except i cant get the RadioButtonList event to trigger with a minor MsgBox response to validate object sender and selected ListItem information.
Page_Load
If Not Page.IsPostBack Then
With Globals.tst
.GetBrandInformation(Page.RouteData.Values("brand"),
Page.RouteData.Values("year"),
Page.RouteData.Values("month"))
'Load up Question DataSet
For Each quest As Question In .Questions
Dim tr As New HtmlControls.HtmlTableRow
Dim td As New HtmlControls.HtmlTableCell
td.Attributes.Add("class", "tdQ") 'Add class attribute to <td> element, creating 'class="tdQ"'
Dim lbl As New Label
lbl.ID = "lbl" & quest.ID
lbl.Text = quest.Text
td.Controls.Add(lbl)
tr.Cells.Add(td)
tblContent.Rows.Add(tr)
tr = New HtmlControls.HtmlTableRow
td = New HtmlControls.HtmlTableCell
td.Attributes.Add("class", "tdA") 'Add class attribute to <td> element, creating 'class="tdA"'
Dim rbl As New RadioButtonList
rbl.ID = "rblT" & .ID & "_Q" & quest.ID
AddHandler rbl.SelectedIndexChanged, AddressOf rbl_SelectedIndexChanged 'Attach generic event handler to control
Dim li As New ListItem
'Load up Answer Dataset
For Each answ As Answer In quest.Answers
li.Text = answ.Value
li.Value = "T" & .ID & "-Q" & quest.ID & "-A" & answ.ID & "-C" & answ.Correct
'Add built ListItem to RadioButtonList
rbl.Items.Add(li)
li = New ListItem
Next
td.Controls.Add(rbl)
tr.Cells.Add(td)
tblContent.Rows.Add(tr)
Next
End With
'
End If
Below is the Generic Event Handler Logic i am trying to attach to the RadioButtonList(s).
Protected Sub rbl_SelectedIndexChanged(sender As Object, e As EventArgs)
MsgBox(CType(sender, RadioButtonList).ID & " Clicked.")
MsgBox("Radio Button Selected: " & CType(sender, RadioButtonList).ID & " is Correct? " & CType(sender, RadioButtonList).SelectedValue)
End Sub
Anyone see anything wrong with the design, or know why the Event is not being triggered?
Edited 2012-11-20
Ok changed the rbl object to do AutoPostBack = true but that made life even more unbearable ;) Then quickly reverted back as the Q&A list i have is randomly generated on the Questions and Answers so the end-user would be given a new random order of questions upon every click of the ListItem.
Although i am getting some response back from the call backs still not getting the JavaScript response i am expecting by using either a defined JavaScript file or inline Response.Write/ClientScript.Register.
Created a debugging method into the Content Page:
Public Shared Sub Show(msg As String, Optional pg As Page = Nothing)
Dim cmsg As String = msg.Replace("'", "\'")
Dim scr As String = "<script type=""text/javascript"">alert('" & cmsg & "');</script>"
If pg Is Nothing Then
pg = CType(HttpContext.Current.CurrentHandler, Page)
End If
If (pg IsNot Nothing) And Not (pg.ClientScript.IsClientScriptBlockRegistered("alert")) Then
pg.ClientScript.RegisterClientScriptBlock(GetType(Alert), "alert", scr)
End If
End Sub
On page Load this method fires and as expected, but when placed inside the SelectedIndexChanged event it never fires off.
Still perplexed on why it works on general execution but not triggered execution.
Userful Method for those that like to create .Net methods that implement Javascript. .Net Slave - Javascript Alert.Show Class
You have to take it OUT of the If Not Page.IsPostBack Then
this is because when you DO postback, the...
AddHandler rbl.SelectedIndexChanged, AddressOf rbl_SelectedIndexChanged
...needs to be rebound before it can fire.
So basically, remove the If Not Page.IsPostBack Then and End If.
Oh, and get rid of the MsgBox() code too - this will kill the page from doing anything. If you want to output an Alert() then do something like:
Dim script As String = String.Format("alert('{0}');", ""Radio Button Selected: " & CType(sender, RadioButtonList).ID & " is Correct? " & CType(sender, RadioButtonList).SelectedValue")
page.ClientScript.RegisterClientScriptBlock(page.[GetType](), "alert", script, True)
UPDATE:
you also want to set AutoPostback = true; on your RBL. This tells the page to postback as soon as it's changed. the handler only fires if AutoPostBack is true.
Is there a Panel or any container with CommandName, CommandArguments instead of using Buttons (LinkButton, ImageButton, ...)?
I want to add a column in a GridView to make selection for the row, the whole cell's rectangle instead of a Select link.
You can make (almost) anything implement CommandName and CommandArguments by implementing the IButtonControl interface. You will probably also want to implement the IPostBackEventHandler interface.
This article covers in detail exactly what you are asking about, generally: making a Panel into a command control. It's not entirely trivial.
But making a table row clickable is a lot easier, though, esp. using jQuery. See this article. You just bind an event to the row, and go from there. In this example, they're redirecting to the url for a link in the row on a click event. You could just as easily do something else like call __doPostBack to cause an async postback and run arbitrary server code, e.g.
Here is another way how you can make a GridView-Cell as Sort-Column(see in RowCreated, the rest is sample-data):
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
If Not IsPostBack Then
BindGridView()
End If
End Sub
Private Sub BindGridView()
Dim source As New List(Of String)(New String() {"1. row", "2. row", "3. row", "4. row", "5. row"})
Me.GridView1.DataSource = source
Me.GridView1.DataBind()
End Sub
Private Sub GridView1_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowCreated
Dim cell As New TableCell
If e.Row.RowType = DataControlRowType.DataRow Then
cell.Text = "select"
cell.ToolTip = "click to select row"
cell.Attributes("onmouseover") = "this.style.cursor='pointer';"
cell.Attributes("onclick") = ClientScript.GetPostBackClientHyperlink(DirectCast(sender, GridView), "Select$" & e.Row.RowIndex)
End If
e.Row.Cells.Add(cell)
End Sub
Edit: if you get a "Invalid postback or callback argument"-Exception from ASP.Net, you can either set EnableEventValidation="False" or add following to your page's codebehind:
Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)
For Each row As GridViewRow In GridView1.Rows
If row.RowType = DataControlRowType.DataRow Then
ClientScript.RegisterForEventValidation(GridView1.UniqueID, "Select$" & row.RowIndex)
End If
Next
MyBase.Render(writer)
End Sub
If you need C#, copy all into: http://www.developerfusion.com/tools/convert/vb-to-csharp/
I have an image button that is created on rowcreated manually in code.
Dim deletecshr As New ImageButton
deletecshr.ImageUrl = "\images\bttnDeletemini.gif"
deletecshr.ToolTip = "This Will Delete All Cashiers"
deletecshr.ID = "deletecshr"
In gridveiw_rowdatabound I have the following:
Dim deletecshr As ImageButton = DirectCast(e.Row.FindControl("deletecshr"), ImageButton)
deletecshr.CommandName = "Delete"
deletecshr.CommandArgument = emp_no & "," & e.Row.Cells(2).Text & "," & e.Row.Cells(1).Text & "," & cashier_no & "," & manager_no
I set the commandname and the argument.
However, in rowcommand it finds no commandname or anything else. What am i doing wrong? I believe this has worked before.
From what i can tell you never attach the event.
Dim deletecshr As New ImageButton
deletecshr.ImageUrl = "\images\bttnDeletemini.gif"
deletecshr.ToolTip = "This Will Delete All Cashiers"
deletecshr.ID = "deletecshr"
AddHandler deletecshr.Command AddressOf deletecshrCommandEventHandler
You'll have a method similar of this in your code:
Protected Sub deletecshrCommandEventHandler(sender As Object, e As CommandEventArgs)
If e.CommandName = "Delete" Then
'Do your stuff
End IF
End Sub
EDIT
Added some more code and fixed a small syntax error.