Missing Controls in page after timer method ticks - asp.net

I have some code that handles a timer method, that just updates a label and changes it to a last updated at this time.
Protected Sub specialNotesTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles specialNotesTimer.Tick
Label1.Text = "Panel refreshed at: " + DateTime.Now.ToLongTimeString()
End Sub
When it ticks however, any other control on the page cannot be found via a button press. Image buttons or my other dynamically created controls, w.e the case, are missing.
I have a function that finds the fired control on the page, then returns the control so I can determine what to do
Public Shared Function GetPostBackControl(ByVal thePage As Page) As Control
Dim myControl As Control = Nothing
Dim ctrlName As String = thePage.Request.Params.Get("__EVENTTARGET")
If ((ctrlName IsNot Nothing) And (ctrlName <> String.Empty)) Then
myControl = thePage.FindControl(ctrlName)
Else
For Each Item As String In thePage.Request.Form
Dim c As Control = thePage.FindControl(Item)
If (TypeOf (c) Is System.Web.UI.WebControls.Button) Then
myControl = c
End If
Next
End If
Return myControl
End Function
This works before the timer.tick, but not after. The control won't be listed as an Item in thePage.Request.Form, and it'll throw a null exception, when I know the control is there.

Related

Maintain Tab index after post back with textchanged

I have 3 textboxes that have AutoPostBack = true. On postback it's losing it's focus. I've been searching and tried many things but nothing is working.
The code below is a snippet of what i'm trying to do.
basically this first snippet isn't grabbing anything. Does anyone know what i'm doing wrong here
**Side note I'm not using Update Panel i'm using LayoutItemNestedControlContainer
Dim ctrl = From control In wcICausedPostBack.Parent.Controls.OfType(Of WebControl)()
Where control.TabIndex > indx
Select control
Protected Sub txtDEPTH_TextChanged(sender As Object, e As EventArgs) Handles txtDEPTH.TextChanged
UpdateProductTemp()
txtDEPTH.Focus()
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
If Page.IsPostBack Then
Dim wcICausedPostBack As WebControl = CType(GetControlThatCausedPostBack(TryCast(sender, Page)), WebControl)
Dim indx As Integer = wcICausedPostBack.TabIndex
Dim ctrl = From control In wcICausedPostBack.Parent.Controls.OfType(Of WebControl)()
Where control.TabIndex > indx
Select control
ctrl.DefaultIfEmpty(wcICausedPostBack).First().Focus()
End If
End Sub
Protected Function GetControlThatCausedPostBack(ByVal page As Page) As Control
Dim control As WebControl = Nothing
Dim ctrlname As String = page.Request.Params.[Get]("__EVENTTARGET")
If ctrlname IsNot Nothing AndAlso ctrlname <> String.Empty Then
control = page.FindControl(ctrlname)
Else
For Each ctl As String In page.Request.Form
Dim c As Control = page.FindControl(ctl)
If TypeOf c Is TextBox OrElse TypeOf c Is DropDownList Then
control = c
Exit For
End If
Next
End If
Return control
End Function
Which version are you using? Because, when I try to set focus() of a Textbox, the compiler gives me an error, because there is no such method. However, HTML provides an attribute, which auto focuses an focusable element.
Solution:
TextBoxToSetFocus.Attributes.Add("autofocus", "")
Regards,
Maheshvara

Visual Studio Have to Click Button Twice

I'm trying to write code that will, at the click of a button, push a string variable onto a page and then open that page. The trouble that I am running into is that variable, a button's text, is nested within a gridview, making accessing it difficult. It is also difficult because I am importing it from an SQL database into the Gridview, so I cannot access it directly from there either. It works with my current code if I use the button's onClick event, but then for some reason I have to click the button twice in order for it to work. I have read on here to instead use the onPreRender event, but that interferes with pushing the string variable onto the page, and I can't have that. Is there any other way to get rid of having to click the button twice that doesn't involve the onPreRender event?
Here is the code:
Imports System.Data.SqlClient
Imports System.IO
Partial Class PartsLookup
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Private Function FindControlRecursive(ByVal RootControl As Control, ByVal ControlID As String) As Control
If RootControl.ID = ControlID Then
Return RootControl
End If
For Each controlToSearch As Control In RootControl.Controls
Dim controlToReturn As Control = FindControlRecursive(controlToSearch, ControlID)
If controlToReturn IsNot Nothing Then
Return controlToReturn
End If
Next
Return Nothing
End Function
Protected Sub Button1Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim clickedButton As Button = sender
MsgBox(clickedButton.Text)
Dim ControlText As Control = FindControlRecursive(GridView1, clickedButton.ID)
Dim ControlText1 As Button = ControlText
Dim MachineNumber As String = ControlText1.Text
If MachineNumber = "" Then
ControlText1.Visible = False
End If
Dim SpecificPart() As String = {String that is the files contents, the middle of which is where the variable will be pushed to}
Dim path As String = "File path where the variable is to be pushed to"
File.WriteAllLines(path, SpecificPart)
clickedButton.PostBackUrl = "~/PartNumberPages/PartTemplate.aspx"
End Sub
End Class

Dynamically generated code-behind button won't fire its event

I have a series of controls (3 labels, 3 text boxes, and 2 buttons) that are created when the user clicks a button on my page. The page does its postback with the commands that will generate these controls. However, when I fill in my textboxes and click one of the newly generated buttons (btnCreate), nothing happens, and the page just reloads once again.
What I want to happen is that when the user clicks btnCreate, it fires its function, and puts the TextBox.Text into a database. But again, when btnCreate is clicked, nothing happens.
Here is the code for the generated buttons (It's the same function that generates the text boxes, which I've excluded here):
Protected Sub createSpecialNotes()
Dim btnCreate As Button = New Button
Dim btnClear As Button = New Button
'Place properties
lblSubject.Text = "subject"
lblSubject.ID = "lblSubject"
lblSubject.Width = 700
lblAgenda.Text = "Agenda Note"
lblAgenda.ID = "lblAgenda"
lblAgenda.Width = 700
lblMinutes.Text = "Minutes Note"
lblMinutes.ID = "lblMinutes"
lblMinutes.Width = 700
btnCreate.Text = "Create"
btnCreate.ID = "btnCreate"
btnClear.Text = "Clear"
btnClear.ID = "btnClear"
'Add handlers for buttons
AddHandler btnCreate.Click, AddressOf btnCreate_Click
AddHandler btnClear.Click, AddressOf btnClear_Click
plhCreateSpecialNotes.Controls.Add(btnCreate)
plhCreateSpecialNotes.Controls.Add(btnClear)
End Sub
And for the sake of simplicity, let's just say btnCreate needs only to display the textboxes' contents.
Edit1: The call for create special notes is on page_preInit. It's call consists of the following
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
'Find the control that was fired
Dim controlFired As Control = GetPostBackControl(Me.Page)
If (controlFired IsNot Nothing) Then
If (controlFired.ClientID.ToString() = "btnCreateSpecial") Then
Call createSpecialNotes()
End If
If (controlFired.ClientID.ToString() = "btnCreate") Then
'i've tried putting things here to no avail.
End If
End If
End Sub
The function getpostbackcontrol looks like this
Public Shared Function GetPostBackControl(ByVal thePage As Page) As Control
Dim myControl As Control = Nothing
Dim ctrlName As String = thePage.Request.Params.Get("__EVENTTARGET")
If ((ctrlName IsNot Nothing) And (ctrlName <> String.Empty)) Then
myControl = thePage.FindControl(ctrlName)
Else
For Each Item As String In thePage.Request.Form
Dim c As Control = thePage.FindControl(Item)
If (TypeOf (c) Is System.Web.UI.WebControls.Button) Then
myControl = c
End If
Next
End If
Return myControl
End Function
I hope this helps to clear things up as to why I'm having trouble.
What would be really useful here is to know when you're calling createSpecialNotes(). But most probably what you are missing is the life-cycle of the page.
Make sure createSpecialNotes() is called OnInit of your page. Anything after that is too late and your event handler won't be fired.
If OnLoad of your page is reached and you haven't yet bound the handler to your control, then it won't be fired.
I recommend that you read this article carefully. http://msdn.microsoft.com/en-us/library/ms178472.aspx

Accessing dynamically created checkbox in user control from container page

I am building a wizard in asp.net. I have an main aspx page which will have NEXT and PREVIOUS button for Navigation. On click of each NEXT or PREVIOUS appropriate user control will be loaded.
In one user control I have to create dynamic checkboxes as shown below:
Public Class ucQuestion
Inherits System.Web.UI.UserControl
#Region "UserControl Events"
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
If Not (Page.IsPostBack) Then
AddControls(0)
End If
Catch ex As Exception
Throw ex
End Try
End Sub
#End Region
Protected Friend Sub AddControls(ByVal iListQuestionCount As Integer)
Try
Dim oExam As New BusinessObject.Wizard.ExamVM
If (System.Web.HttpContext.Current.Session(BusinessLayer.Constants.WizardObjectCollection) IsNot Nothing) Then
oExam = DirectCast(System.Web.HttpContext.Current.Session(BusinessLayer.Constants.WizardObjectCollection), BusinessObject.ExamWizard.ExamVM)
End If
'divQuestion.Controls.Clear()
Dim ctrl As New Literal
ctrl.ID = "lit" + iListQuestionCount.ToString()
ctrl.Text = oExam.Wizard.ExamQuestions(iListQuestionCount).Label
divQuestion.Controls.Add(ctrl)
For iLoopChildCount As Integer = 0 To oExam.Wizard.ExamQuestions(iListQuestionCount).Choices.Count - 1
Dim childctrl As New CheckBox
'childctrl.AutoPostBack = True
childctrl.ID = "chk" + (iLoopChildCount + 1).ToString()
childctrl.Text = oExam.Wizard.ExamQuestions(iListQuestionCount).Choices(iLoopChildCount).Label
childctrl.Checked = oExam.Wizard.ExamQuestions(iListQuestionCount).Choices(iLoopChildCount).IsSelected
'AddHandler childctrl.CheckedChanged, AddressOf OnCheckedClick
divQuestion.Controls.Add(childctrl)
Next
Catch ex As Exception
Throw ex
End Try
End Sub
NoW the problem is in my Main.aspx page if user has selected any checkbox in usercontrol I want to save the value in session on NEXT button Navigation click event.
I tried following code in NEXT Button Click but it was unsucessfull.
For iLoopChildCount As Integer = 0 To oExamQuestions(ListIndex).Choices.Count - 1
Dim ctrl As Control
If (ucQuestion1.FindControl("chk" + (iLoopChildCount + 1).ToString()) IsNot Nothing) Then
ctrl = DirectCast(ucQuestion1.FindControl("chk" + (iLoopChildCount + 1).ToString()), CheckBox)
If (DirectCast(ctrl, CheckBox).Checked) Then
oBallotQuestions(ListIndex).Choices(iLoopChildCount).IsSelected = True
End If
End If
Next
That's the hard way.
Here is the easy way.
Define an interface and implement it in the User Control that represents this action. This might be GetNamesOfSelectedValues or whatever is appropriate. (Technically an interface isn't required, but I find it good practice and it makes for "more well defined contracts" in many cases.)
Use the interface defined on said Child in the Parent page code. Use this only after the OnLoad of the Child Control (which happens after the page load event) or the controls will not be restored yet.
That is, the parent should not know about any controls in the custom User Control.
This approach works well.

get value of label when button clicked in nested repeater asp.net vb

I have nested repeaters, each item in the nested repeater has a label and a button on it, i want to beable to access the label.text when the button is clicked, I think i'm nearly there as I can return the index of the repeater and nested repeater that is clicked, i'm just having some trouble finding the label itself.
You might be able to help me without me posting the repeater code. Here is my code behind for when the button is clicked.
Protected Sub btnEditUser_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim btnEditUser As Button = DirectCast(sender, Button)
Dim reClient As RepeaterItem = DirectCast(btnEditUser.NamingContainer.Parent.Parent, RepeaterItem)
Dim reUser As RepeaterItem = DirectCast(btnEditUser.NamingContainer, RepeaterItem)
Dim selectedClient As Integer = reClient.ItemIndex
Dim selectedUser As Integer = reUser.ItemIndex
Dim UserId As Label = DirectCast(reClients.Items(selectedClient).FindControl("lUserName"), Label)
Response.Write(selectedClient & " " & selectedUser & " " & UserId.Text)
End Sub
I'm currently getting this error 'Object reference not set to an instance of an object.' when trying to write the value of UserId.Text so i think i've got it slightly wrong in this line:
Dim UserId As Label = DirectCast(reClients.Items(selectedClient).FindControl("lUserName"), Label)
This is just a guess, but sometimes you get errors like this when not all rows contain the control you're looking for. Often the code loops through the rows in order, hits a header row first that doesn't contain the relevant control, and fails.
Here is a good MSDN article - Locating a Control Inside a Hierarchy of Naming containers.
Private Function FindControlRecursive(
ByVal rootControl As Control, ByVal controlID As String) As Control
If rootControl.ID = controlID Then
Return rootControl
End If
For Each controlToSearch As Control In rootControl.Controls
Dim controlToReturn As Control =
FindControlRecursive(controlToSearch, controlID)
If controlToReturn IsNot Nothing Then
Return controlToReturn
End If
Next
Return Nothing
End Function
Try it,
Dim UserId As Label =DirectCast(FindControlRecursive(repClient,"lUserName"),Label)

Resources