Send parameter to addhandler? - asp.net

I have a button in a grid that I created programmatically. The button edits some data in a table using data in a hidden column of the grid that the button is in. Normally I send a hidden field the row data using javascript onclientclick of the button then make the changes to the database using that hidden field. But there must be a way to send the addhandler of the button a parameter. This is the code i have to clarify....
Dim btnedit As New ImageButton
AddHandler btnedit.Click, AddressOf btnedit_Click
btnedit.ImageUrl = "\images\bttnEditMini.gif"
If e.Row.RowType <> DataControlRowType.Header And e.Row.RowType <> DataControlRowType.Footer Then
e.Row.Cells(3).Controls.Add(btnedit)
End If
here is my Addhandler with its delegate:
Public Delegate Sub ImageClickEventHandler(ByVal sender As Object, ByVal e As ImageClickEventArgs)
Sub btnedit_Click(ByVal sender As Object, ByVal e As ImageClickEventArgs)
//programming stuff
End Sub
How can i send this handler a parameter?

By convention, all event handlers accept two parameters: the sender, and the EventArgs. If you need to send custom information to the listeners, create a new class that inherits from EventArgs and contains the information that you need to communicate.
Check out this article on CodeProject that shows you how to do this.

Short answer: no. Where would you send it? You've got two parameters.
Longer answer: sender is the control that sent the event. In this case, it will be your btnEdit control. Maybe that will help you.

Since it was in a grid i just used the row command instead. And when Row command is used you can send it a commandname and a commandargument. I passed my parameter as the argument.
GridView1.Rows(i).Cells(3).Controls.Add(btndel)
btndel.ImageUrl = "\images\bttnDelete.gif"
btndel.ToolTip = "This will delete the Selected Assignment"
btndel.CommandName = "destroy"
btndel.CommandArgument = GridView1.Rows(i).Cells(0).Text
btndel.Attributes.Add("onclick", "javascript: if(confirm('Are you sure you want to delete this Department Cost Days Assignment?')==false) return false;")
here is the rowcommand:
Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
If e.CommandName = "destroy" Then 'used destroy because Delete command was prohibited.
Call Connection()
Dbcmd.CommandText = "Delete from table where condition = '" & e.CommandArgument & "'"
Dbcmd.ExecuteNonQuery()
Dbconn.Close()
Dbconn.Dispose()
End If

If you don't want to use the 'default'/already defined parameters, you can create your own events.

Related

CommandArgument on SQLDatasource Inserted?

I'm wishing to redirect to two different pages depending on which button is pressed on my form.
Both buttons call the Insert method of the Datasource, but only one of them needs to get hold of the newly inserted GUID and redirect using that GUID.
I'm doing it using this code
Protected Sub DSCustomers_Inserted(sender As Object, e As SqlDataSourceStatusEventArgs) Handles DSCustomers.Inserted
Response.Redirect("~/addTicket.aspx?step=2&customerID=" & e.Command.Parameters("#customerID").Value.ToString)
End Sub
But how can I know if it's the other button that has been pressed and doesn't need to redirect?
I can't get access to the CommandArgument otherwise I would just check which button has been pressed using that and then redirect accordingly.
Thanks
You can't just use a global private boolean?
Dim RedirectButtonPressed As Boolean = false
Protected Sub RedirectButton_Click(sender As Object, e As EventArgs) Handles RedirectButton.Clicked
// code code code
RedirectButtonPressed = True
End Sub
Protected Sub DSCustomers_Inserted(sender As Object, e As SqlDataSourceStatusEventArgs) Handles DSCustomers.Inserted
If RedirectButtonPressed Then
Response.Redirect("~/addTicket.aspx?step=2&customerID=" & e.Command.Parameters("#customerID").Value.ToString)
RedirectButtonPressed = False
End If
End Sub

How to hook up ClickI() event for ImageButton in code behind ASP.NET

I have a ImageButton instance variable in my custom control I am making. I am a little shaky on how to simply set up it's event handler for it's click event. Coming from C#, I am a little confused as this is in VB.NET.
Snip:
Dim ctrlCloseImage As ImageButton = New ImageButton()
With ctrlCloseImage
.ID = "imgClose"
.ImageUrl = "~/Web/Images/close.gif"
.ToolTip = "Close"
.CssClass = "popup_close_img"
'This is where I left off
AddHandler ctrlCloseImage.Click, AddressOf testSub(ctrlCloseImage, ??)
End With
Me._ctrlCloseImage = ctrlCloseImage
And Then:
Protected Sub testSub(ByVal Sender As Object, ByVal e As ImageClickEventArgs)
Me.Page.Response.Write("Yay, you clicked the image button!")
End Sub
Thanks for any help, and if I am missing anything important code-snip wise please let me know. Again, I am wanting this to fire server side, I am not interested in firing off a javascript function here.
You just have to add the delegate:
AddHandler ctrlCloseImage.Click, AddressOf testSub
You cannot pass arguments since the event is not triggered here.
However, if you don't need to create a control dynamically (normally that's unnecessary) you could either register the event on the aspx or with the Handles clause(as opposed to C#):
Protected Sub testSub(ByVal Sender As Object, ByVal e As ImageClickEventArgs) _
Handles ctrlCloseImage.Click
Me.Page.Response.Write("Yay, you clicked the image button!")
End Sub
You need to assign the click event a handler :
AddHandler ctrlCloseImage.Click, AddressOf testSub
This will assign the Click control the handler of address testSub
This should do the trick (just put the name of the method afyer AddressOf):
AddHandler ctrlCloseImage.Click, AddressOf testSub

Get a webuserControl's value automatically created

I have added a WebUserControl dynamically ,and then i wanted to get it, here is my story :( i don't know how to do it , here is my code,
thanks in advance,
Protected Sub btngenerate_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btngenerate.Click
For Each Str As String In Tstring
Dim addressControl As WebUC = CType(LoadControl("WebUC.ascx"), WebUC)
addressControl.plbl.Text = Str
form1.Controls.Add(addressControl)
Next
End Sub
Protected Sub btnOk_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOk.Click
'here is what i did , but it didn't work
'For Each ct As WebUCIn form1.Controls
' ltlres.Text = ltlres.Text & ", " & ct.plbl.Text & " " & ct.ptxt.Text
'Next
End Sub
There is a rule to adding controls dynamically. You had to add them back on Init for as long as you need them.
Just adding them on a button click will show them the first time, but you will not receive any inputs from them.
You can keep a flag in the session to denote that they have to be added on Init
Because you added that control dynamically, when you post back, you'll need to add it again in order for its ViewState and postback data to be associated with it.
Re-create it in the Init event, and then when you process control events (like button clicks) it will exist and will have its data (such as the contents of its child controls) associated with it.
Since you're creating the control as a response to another event, you'll need to keep some kind of flag (a boolean? A counter?) in Session in order to know whether or not to re-create it on Init.

RowDataBound DropDownList

I have a RowDataBound event handler that looks like this:
Public Sub CustomersGridView_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles GVHistoricNames.RowDataBound 'RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim hyperlinkUSNHyperlink As HyperLink = CType(e.Row.FindControl("USNHyperlink"), HyperLink)
Dim ddl As DropDownList = CType(e.Row.FindControl("ddlUsercode"), DropDownList)
If ddl.SelectedValue = "" Then 'labLastUserCode.Text = "" Then
hyperlinkUSNHyperlink.NavigateUrl = ""
End If
End If
End Sub
...and a RowCreated event handler that looks like this:
Public Sub CustomersGridView_RowCreated(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles GVHistoricNames.RowCreated 'RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim ddl As DropDownList = CType(e.Row.FindControl("ddlUsercode"), DropDownList)
ddl.Items.Add("")
ddl.Items.Add(strUserName)
End If
End Sub
...and a RowUpdating event handler that looks like this:
Protected Sub GVHistoricNames_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles GVClearcoreHistoricNames.RowUpdating
Try
Dim ddl As DropDownList = CType(GVHistoricNames.Rows(e.RowIndex).FindControl("ddlUsercode"), DropDownList)
SQLHistoricNames.UpdateParameters("UserCode").DefaultValue = ddl.SelectedValue
Catch ex As Exception
Finally
End Try
End Sub
Please see line three of the RowUpdating event handler. The value of the SelectedValue property is never correct because the RowDataBound event handler is called after the RowUpdating event handler. How do I access SelectedValue? I want to set it as an update parameter.
One of the way could be to look into the actual request data. For example, in GVHistoricNames_RowUpdating code, use
Dim ddl As DropDownList = CType(GVHistoricNames.Rows(e.RowIndex).FindControl("ddlUsercode"), DropDownList)
SQLHistoricNames.UpdateParameters("UserCode").DefaultValue = Request(ddl.UiniqueID)
I often use such work-arounds when the control value is needed before post data could be loaded into control (or when controls are added/bound dynamically at a later event).
EDIT
ASP.NET uses Control.UniqueId to represent name property of corresponding html element. It (as well as ClientID) typically gets constructed by appending control's id to parent's (parent that is naming container) unique id, hence you get different unique ids (and client ids) for multiple drop-down lists in the grid (because each row acts as a naming container)
As far as your problem goes, you are probably creating drop-down list in design time template while you are loading your list items in row created. However, before row-created event is fired, the drop-down list would have been already added to page control tree and its POST events would have been already processed. In such case, there would be no items in the drop-down list at that time to set the selection. Hence the issue.

How to get Command Functionality from a Panel

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/

Resources