VB. NET ASPX: find controls triggers and call it dynamically - asp.net

I am looking for a way, that knowing a controls name, to raise them or call the processes event/code behind.
I am using VB .NET in VS2010
I have an aspx page with a selection of checkboxes in a panel, each checkbox has its own trigger. I have code that saves a list of checked checkboxes. I have code that restores the checked states to those checkboxes, but I need to execute the associated code to the checkboxes checkchanged event.
' Read db to get saved list of checkboxes '
For each result from db
Dim cb As CheckBox
cb = 'a function that finds and returns the control'
' Now that I have the control,
' how can I find and execute it's checkedchanged code?
The control return function is working because in testing, I can process cb.checked = true, and the cb becomes checked, but this doesn't raise the event/trigger the code.
Example of associated checkedchanged subs:
Protected Sub cb_use_rc3_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs) Handles cb_use_rc3.CheckedChanged
Protected Sub cb_use_casestatus_CheckedChanged(sender As Object, e As EventArgs) Handles cb_use_casestatus.CheckedChanged
Any ideas?

For Each grd_Row As GridViewRow In gvPersonalInventario.Rows
Dim cb As New Web.UI.WebControls.CheckBox
cb = grd_Row.FindControl("CheckBox2")
If cb.Checked = True Then
label1.text = grd_Row.Cells(0).Text
End If
Next

OK, I'm working on the assumption that your checkboxes each have an individual ID and are not generated by a bound control of any sort.
While it is possible to determine what handler is hooked up to what event of what object (or so I understand), it's probably more trouble than it's worth for this limited case.
The simplest, though ugliest, way to do it would be this:
Follow Mr. Schmelter's advice and isolate the business logic in meaningfully-named methods. Call them from each event handler rather than putting all the logic in the event handler.
Since you have the control, you can determine its ID. Use a Select Case statement with the ID of the control to determine which method or methods from #1 to call.

Related

ASP.Net Repeater: Checkboxes checked status not persisting on form submission

I have a Repeater of checkboxes bound in code-behind:
<asp:Repeater runat="server" ID="rptOpenJobs" OnItemDataBound="rptOpenJobs_ItemDataBound">
<ItemTemplate>
<asp:CheckBoxList ID="lstOpen" runat="server"></asp:CheckBoxList>
</ContentTemplate>
</asp:Repeater>
Code-behind (VB.Net):
Protected Sub rptOpenJobs_ItemDataBound(sender As Object, e As RepeaterItemEventArgs)
Dim jobsTable As New DataTable
Dim conn As String = "[hidden]" 'Connection String to retrieve data table values
If e.Item.ItemType.Equals(ListItemType.AlternatingItem) Or e.Item.ItemType.Equals(ListItemType.Item) Then
Dim cboxlist As CheckBoxList = e.Item.FindControl("lstOpen")
If cboxlist.Items.Count = 0 Then
cboxlist.DataSource = jobsTable
cboxlist.DataTextField = "job_title"
cboxlist.DataValueField = "job_title"
cboxlist.DataBind()
End If
End If
End Sub
On form submission, the checked boxes do not stay checked. I've looked for solutions but haven't found any where the list is databound in code-behind.
I've tried adding an UpdatePanel around the repeater and around the CheckBoxList but the checked state still will not persist on form submission.
What does you page load event look like?
You ONLY load things up the first time in the If IsPostBack = False code stub.
99% if not 100% of your pages will ahve that code block. For me, comming from say Access, VB6, vb.net? Well a form loads, and we have the form load event.
but, any old button click on that page ALSO triggers a post back, and the on load event will run EVERY time (and then the button click or whatever event code will run).
So, all web pages look like this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
' the REAL first time load event!!!
LoadGrid()
End If
End Sub
Sub LoadGrid()
Using cmdSQL As New SqlCommand("SELECT ID, FirstName, LastName, HotelName, City from tblHotels",
New SqlConnection(My.Settings.TEST3))
cmdSQL.Connection.Open()
GridView1.DataSource = cmdSQL.ExecuteReader
GridView1.DataBind()
End Using
End Sub
So note how we have that first page load event - we load up a grid. But if we do NOT put that code inside of of the IsPostBack = False part, then our setup code and our load code will run every time on a full page post back.
Your check boxes as you have should persist for you, and should survive a page post back.
I don't see where (how) you persisted the jobs table, but ONCE the repeater is loaded, they should survive a post back. I mean, the data bound event only triggers if you are re-binding the repeater. but, if you are say due to adding new rows or some such, and you do trigger (need/want) a databind event again, then that jobsTable does need to exist and be persisted if you do re-bind the repeater.
So, in your code, you have on page load, we load up the Repeater. Above code would be the same, eg this:
And since the table is used OVER and OVER for each item data bound event, then we should NOT re-pull the table each time in the item data bound event. We should setup (load) that table one time in our LoadGrid routine.
So, at the page level class, we will declarer a table variable scoped to the form/page level. This will persist long enough during each item bind event for the repeater to fill out the check box list.
We assume that you have a data source for hte repeter - it will repeat many times. And for EACH repeater, we have a checkbox list that ALSO has a set of values that we want to fill from the check box list of choices.
It is NOT 100% clear if each new check box list is to be driven from ONE table, and each repeated row of course does have a value from the table for each row of the repeating list that represents the chosen check box value.
Or, is the list of check box values for each repeated item different? This issue has to be cleared up.
Clear this last issue up for me, and I post more code as to how this can work.
Sub LoadGrid()
Using cmdSQL As New SqlCommand("SELECT ID, FirstName, LastName, HotelName, City from tblHotels",
New SqlConnection(My.Settings.TEST3))
cmdSQL.Connection.Open()
rptOpenJobs.DataSource = cmdSQL.ExecuteReader
rptOpenJobs.DataBind()
End Using
End Sub

How to use RadDatePicker inside RadGrid?

Wasn't able to find anything about this situation:
I have two RadDatePicker inside RadGrid for start and end date change
<telerik:RadDatePicker ID="rdpStartDate" Skin="Library" EnableEmbeddedSkins="false" CommandName="StartDateChange" runat="server" />
By itself, they work fine, but now I have a situation when I need to call method when their value has been changed (CommandName was added for this)
I know how to do this outside RadGrid, basically:
Protected Sub rdpStartDateChanged(ByVal sender As Object, ByVal e As Telerik.Web.UI.Calendar.SelectedDateChangedEventArgs) Handles rdpStartDate.SelectedDateChanged
...
...
End Sub
But I wasn't able to do this inside RadGrid, because nothings seems to trigger it.
I tried to catch my command with this (works for buttons at least):
Protected Sub rgLibraryItemCommand(ByVal sender As Object, ByVal e As GridCommandEventArgs) Handles rgLibrary.ItemCommand
But, no, it doesn't see CommandName="StartDateChange"
What I need to do to be able to catch those Date change events if RadDatePicker
is placed inside RadGrid?
You need to identify the control inside the grid which triggers the action. I'm not sure which is the way for Rad to do that but it should be similar this:
Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellButtonClick
'TODO - Button Clicked - Execute Code Here
End Sub
So you need to find the events for the DataGridViewRow for Rad and substitute them with the ones cell clicking events. This example should get you started.
Subscribing to an event on a control inside a RadGrid does not work the same way, because there could be multiple copies of the control or even none at all, depending on how many records are in the Data Source. Therefore, in order to subscribe to events on these controls, you have to do it manually after the data is bound, either in the ItemCreated event or ItemDataBound event.
Protected Sub rgLibraryItemCreated(ByVal sender as Object, ByVal e As GridItemEventArgs) Handles rgLibrary.ItemCreated
If TypeOf e.Item Is GridDataItem Then
Dim item As GridDataItem = e.Item
Dim rdpStartDate As RadDatePicker = item.FindControl("rdpStartDate")
AddHandler rdpStartDate.SelectedDateChanged, AddressOf rdpStartDateChanged
End If
End Sub

UpdatePanel Crashing Other Update Panels Not Working

I have very strange issues. I have used Update Panels before and never had issues but because I am grouping listviews I get the issues. I have about 4 Update Panels on a page which I call by using the panelname.update() in code behind, and used to all work.
Then because I had to group a bunch of listviews inside each other I had to use a PageLoad to DataBind rather than actually putting the data sources on the asp page. The data all works with Listview when page loads, but now the update panels don't work on async postback at all.
If I take out uppnlSOL.Update() in code behind all the rest start working again. The update panel that causes the issue is the same one that contains the listview with the DataBind.
ASP page has all panels have childrenastriggers="false" UpdateMode="Conditional" hence I call them all from code behind. I also tried removing the uppnlSOL.Update() from code behind and placing a trigger on the uppnlSOL on the asp page. As soon as it launches I get same result. I removed the trigger then the other 3 panels work again. I need all 4 working and
I am confused, its almost like its rendering while its trying to do the update panel or something. I even tried a pause for 3 seconds after DataBind then trying updatepanel.Update() and all 4 still didn't work.
I will try to put some code below of what is sort of going on.
Protected Sub Packing_Load(sender As Object, e As EventArgs) Handles Me.Load
If IsPostBack = False Then
lvSOLGrpDelAdd.DataSource = tblDespatchA.DespatchPackSOLGrpDelAdd_Get(IDSO:=hdnIDSO.Value)
lvSOLGrpDelAdd.DataBind()
End If
End Sub
Protected Sub lvSOLGrpDelAdd_RowDataBound(sender As Object, e As ListViewItemEventArgs) Handles lvSOLGrpDelAdd.ItemDataBound
Dim lvSOLGrpDelMeth As ListView = DirectCast(e.Item.FindControl("lvSOLGrpDelMeth"), ListView)
lvSOLGrpDelMeth.DataSource = tblDespatchA.DespatchPackSOLGrpDelMeth_Get(IDSO:=hdnIDSO.Value, IDGrpDelAdd:=DataBinder.Eval(e.Item.DataItem, "IDGrpDelAdd"))
lvSOLGrpDelMeth.DataBind()
End Sub
Protected Sub lvSOLGrpDelMeth_RowDataBound(sender As Object, e As ListViewItemEventArgs)
Dim lvSOL As ListView = DirectCast(e.Item.FindControl("lvSOL"), ListView)
lvSOL.DataSource = tblDespatchA.DespatchPackSOL_Get(IDSO:=hdnIDSO.Value, IDGrpDelAdd:=DataBinder.Eval(e.Item.DataItem, "IDGrpDelAdd").ToString, IDGrpDelMeth:=DataBinder.Eval(e.Item.DataItem, "IDGrpDelMeth").ToString)
lvSOL.DataBind()
End Sub
Protected Sub btnAllocateLine_Click(sender As Object, e As EventArgs)
Dim lvRow As Object = DirectCast(sender, Object).Parent
Dim hdnIDSOL As HiddenField = DirectCast(lvRow.FindControl("hdnIDSOL"), HiddenField)
Dim lstQtyAvail As DropDownList = DirectCast(lvRow.FindControl("lstQtyAvail"), DropDownList)
tblDespatchA.DespatchPackSOLAllocate_Save(IDSO:=hdnIDSO.Value, IDSOL:=hdnIDSOL.Value, AllocateQty:=lstQtyAvail.SelectedValue)
Bind()
End Sub
Protected Sub Bind()
uppnlDOL.DataBind()
uppnlDOL.Update()
uppnlDBox.DataBind()
uppnlDBox.Update()
uppnlFooter.DataBind()
uppnlFooter.Update()
'I HAVE TO REGET FROM DATABASE CHANGES THAT HAVE HAPPEN AND
'I KNOW THIS BIT WORKS BECAUSE I HAVE TESTED THE DATA.
lvSOLGrpDelAdd.DataSource = tblDespatchA.DespatchPackSOLGrpDelAdd_Get(IDSO:=hdnIDSO.Value)
lvSOLGrpDelAdd.DataBind()
uppnlSOL.Update() ' THIS BIT WHEN I PUT IN THIS MAKES ALL THE OTHER PANELS CRASH
End Sub
Here we go again I answer my own question because nobody would help, but I will help anyone else with similar situation because I'm nice.
The reason it crashed all the other panels is because on my ASP.net page had some generated code in there using <% Response.Write("stuff here") %> and because of using the Response.Write caused it crash.
The Update Panels are doing a async post back and me calling a Response.Write() at the same time as PanelName.Update() caused this issue. I am looking for another method to write to the screen without using response.write and that would solve my 2nd problem.
Any Ideas would be appreciated.

Setting focus to a textbox within an UpdatePanel

I have four textboxes within an UpdatePanel, and AutoPostBack is set to True for all of them. When the user enters a value and hits Enter, I want the cursor to move to the next textbox automatically. When I don't have the controls in an UpdatePanel, the standard textbox.focus method works fine.
I found some code here that led me to create this:
Protected Sub txtField_TextChanged(ByVal sender As Object, ByVal e As EventArgs) Handles txtField1.TextChanged,
txtField2.TextChanged, txtField3.TextChanged
'Based on the textbox where data was changed, move the cursor to the next field.
Try
Dim sm As ScriptManager = ScriptManager.GetCurrent(Me)
'As multiple textboxes fire this same event, determine which textbox triggered this.
Dim MyTextbox As TextBox = TryCast(sender, TextBox)
Select Case MyTextbox.ID.ToString
Case "txtField1"
sm.SetFocus(txtField2)
Case "txtField2"
sm.SetFocus(txtField3)
Case "txtField3"
sm.SetFocus(txtField4)
End Select
Catch ex As Exception
lblError.Text = "Error in [txtField_TextChanged]: " & ex.Message
End Try
End Sub
What is really strange is that this works ONCE on whatever field I try first. After that, the event is fired, but the focus does not change. Is there something additional I need to to for subsequent calls?
I would appreciate any suggestions. Thank you!
Try setting the EnablePartialRendering property of the ScriptManager to false, like so:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="false"></asp:ScriptManager>
I hope this helps! Good luck, and happy coding :)

Unable to get values from Value property of HtmlInputHidden

I have a custom control that inherits from .NET's CompositeControl class. This control overrides the CreateChildControls in order to build its child controls dynamically. I need the page to post back after a couple different javascript events occur on the client side.
In order to accomplish this, I create two hidden controls on the page so I can set their values with javascript, submit the page, and read the values out on server side. Here's is the code I use to create these two hiddens:
Protected Overrides Sub CreateChildControls()
hdEventName = New HiddenField()
Controls.Add(hdEventName)
hdEventName.ID = "hdEventName"
hdEventArgs = New HiddenField()
Controls.Add(hdEventArgs)
hdEventArgs.ID = "hdEventValue"
' other controls
' ...
End Sub
When a javascript event occurs I set the value attribute of the two hiddens and submit the page, like so:
hdEventName.value = 'EventName';
hdEventArgs.value = 'arg1,arg2';
document.forms[0].submit();
In the OnLoad method of my control, I attempt to check the Value property of the hdEventName and hdEventArgs controls, but it is always empty. However, Page.Request.Form(hdEventName.UniqueID) and Page.Request.Form(hdEventArgs.UniqueID) return correct values. The actual HTML in the markup also shows correct values after the page posts back.
Why is the Value property of the HtmlInputHiddens disconnected from the actual value that appears on the client?
Update
It appears that a control's properties get loaded from the form sometime after OnLoad occurs. Thus I was able to solve my problem by either moving the code that checks the two hidden fields into the OnPreRender method, or adding the following method to my code -
Private Sub Event_Handler(ByVal sender As Object, ByVal e As EventArgs)
Handles hdEventName.ValueChanged
' do stuff with hiddens
' ...
' reset the values back
hdEventName.Value = String.Empty
hdEventArgs.Value = String.Empty
End Sub
when the page posts back there's nothing to link the variable hdEventName to the control you previously created. what you're doing is akin to having an integer declared at the class level and setting it to 5 when you're creating child controls. there's nothing to maintain that value in that variable across postbacks.
if you want to get a reference to the control you created previously, you'd have to use
hdEventName = CType(Page.FindControl("hdEventName") , HiddenField)
(i'm guessing at this) or Request if you're only concerned with the value.
It appears that a control's properties get loaded from the form sometime after OnLoad occurs. Thus I was able to solve my problem by either moving the code that checks the two hidden fields into the OnPreRender method, or adding the following method to my code -
Private Sub Event_Handler(ByVal sender As Object, ByVal e As EventArgs)
Handles hdEventName.ValueChanged
' do stuff with hiddens
' ...
' reset the values back
hdEventName.Value = String.Empty
hdEventArgs.Value = String.Empty
End Sub

Resources