ASP.NET How to do For Loop with Controls - asp.net

For Each Control In Page.Header.Controls
How can I do something as above, at the moment getting the error
"Control is a Type and Cannot be used as an expression"
The Complete Code is as follows
Try
' I only do this on my production servers, so I declare those here.'
If Request.ServerVariables("server_name") = "www.myproductionurl.com" Then
' Allow scripts and css to logged in CMS users'
Dim checkLogin As New Controls.Login
If checkLogin.IsLoggedIn <> True Then
For Each Control In Page.Header.Controls
If Control.GetType.Name = "EktronJsControl" Or Control.GetType.Name = "EktronCssControl" Or Control.GetType.Name = "EktronModalCss" Then
Page.Header.Controls.Remove(Control)
Else
' Removes the extra bubble inline style stuff that wasn't put in a CSS.''
Dim litControl As LiteralControl = Control
If litControl.Text = Nothing Then
litControl.Text = ""
End If
' Removing blank.css file'
Dim htmlLink As HtmlLink = Control
If htmlLink.Href = "/css/blank.css" Then
Page.Header.Controls.Remove(Control)
End If
End If
Next
End If
End If
Catch ex As Exception
End Try`

Sadly... VB.NET compiler says you cannot use "Control" as variable name because "Control" is a type too!!
Just use another identifier :)

Since "Control" is a Class, it can not be used as a variable name. Either change it to another variable name, or surround it in square brackets ... [Control]
The brackets will tell the compiler to treat it as a variable rather than class name.

Change Control variable name to something else.
For Each ctrl In Page.Header.Controls
or
For Each ctrl As Control In Page.Header.Controls
The error message says it all: The word Control is a Type so you need to use something else.
UPDATE in response to comments.
You cannot remove the controls while your using a For Each loop to iterate through them.
Consider changing the code to something like:
For i as Integer = Page.Header.Controls.Length -1 to 0 Step -1
Dim ctrl As Control = CType(Page.Header.Control(i),Control)
If ctrl.GetType.Name = "EktronJsControl" Or ctrl.GetType.Name = "EktronCssControl" Or ctrl.GetType.Name = "EktronModalCss" Then
Page.Header.Controls.Remove(ctrl)
Else
Dim litControl As LiteralControl = ctrl
If litControl.Text = Nothing Then
litControl.Text = ""
End If
End If
Next
Or you could keep a reference to the controls to be removed and remove them after the loop.
Dim removables = New List(Of Control)
For Each ctrl In Page.Header.Controls
If ctrl.GetType.Name = "EktronJsControl" Or ctrl.GetType.Name = "EktronCssControl" Or ctrl.GetType.Name = "EktronModalCss" Then
removables.Add(ctrl)
Else
Dim litControl As LiteralControl = ctrl
If litControl.Text = Nothing Then
litControl.Text = ""
End If
End If
Next
For Each c In removables
Page.Header.Controls.Remove(c)
Next
Also, its unlikely that ctrl will be able to be converted into a LiteralControl and an HtmlLink so you need to add extra checks to determine which it is.

First, I'd like to say I'm sorry that you're working with Ektron :(. I feel your pain.
The syntax of your loop is wrong, you need to specify a variable for your loop. The syntax is:
For Each [variable] As [type] In [collection]
So, change your loop to:
For Each ctrl as Control In Page.Header.Controls
And change all the references for the variable Control in your code to be ctrl.
For more info, see the MSDN article on For Each.

Make a list of Controls to remove after you have enumerated then remove them.
Dim controlsToRemove As New List(Of Control)
For Each ctrl In Page.Header.Controls
If ctrl.GetType.Name = "EktronJsControl" Or ctrl.GetType.Name = "EktronCssControl" Or ctrl.GetType.Name = "EktronModalCss" Then
Page.Header.Controls.Remove(ctrl)
Else
Dim litControl As LiteralControl = ctrl
If litControl.Text = Nothing Then
litControl.Text = ""
End If
Dim htmlLink As HtmlLink = ctrl
If htmlLink.Href = "/css/blank.css" Then
'Page.Header.Controls.Remove(ctrl)
controlsToRemove.Add(ctrl)
End If
End If
Next
For Each ctrlToRemove In controlsToRemove
Page.Header.Controls.Remove(ctrlToRemove )
Next

Related

Loop through website links and get PDF's to my computer

This topic is related to Loop through links and download PDF's
I am trying to convert my current VBA code into VBScript. I have already understood that I have to remove the variable types (As ... part of Dim statements) and use CreatObject to get those objects but otherwise everything should port as-is. DoEvents will also have to be replaced with something like Wscript.sleep.
I came up with some problems. Currently while running VBS file I am getting an error saying "Object required: 'MSHTML'". Pointing to line 65, where I have Set hDoc = MSHTML.HTMLDocument. I have tried to search on Google but got nothing helpful for this one.
How I should proceed with this one?
DownloadFiles("https://www.nordicwater.com/products/waste-water/")
Sub DownloadFiles(p_sURL)
Set xHttp = CreateObject("Microsoft.XMLHTTP")
Dim xHttp
Dim hDoc
Dim Anchors
Dim Anchor
Dim sPath
Dim wholeURL
Dim internet
Dim internetdata
Dim internetlink
Dim internetinnerlink
Dim arrLinks
Dim sLink
Dim iLinkCount
Dim iCounter
Dim sLinks
Set internet = CreateObject("InternetExplorer.Application")
internet.Visible = False
internet.navigate (p_sURL)
Do Until internet.ReadyState = 4
Wscript.Sleep 100
Loop
Set internetdata = internet.document
Set internetlink = internetdata.getElementsByTagName("a")
i = 1
For Each internetinnerlink In internetlink
If Left(internetinnerlink, 36) = "https://www.nordicwater.com/product/" Then
If sLinks <> "" Then sLinks = sLinks & vbCrLf
sLinks = sLinks & internetinnerlink.href
i = i + 1
Else
End If
Next
wholeURL = "https://www.nordicwater.com/"
sPath = "C:\temp\"
arrLinks = Split(sLinks, vbCrLf)
iLinkCount = UBound(arrLinks) + 1
For iCounter = 1 To iLinkCount
sLink = arrLinks(iCounter - 1)
'Get the directory listing
xHttp.Open "GET", sLink
xHttp.send
'Wait for the page to load
Do Until xHttp.ReadyState = 4
Wscript.Sleep 100
Loop
'Put the page in an HTML document
Set hDoc = MSHTML.HTMLDocument
hDoc.body.innerHTML = xHttp.responseText
'Loop through the hyperlinks on the directory listing
Set Anchors = hDoc.getElementsByTagName("a")
For Each Anchor In Anchors
'test the pathname to see if it matches your pattern
If Anchor.pathname Like "*.pdf" Then
xHttp.Open "GET", wholeURL & Anchor.pathname, False
xHttp.send
With CreateObject("Adodb.Stream")
.Type = 1
.Open
.write xHttp.responseBody
.SaveToFile sPath & getName(wholeURL & Anchor.pathname), 2 '//overwrite
End With
End If
Next
Next
End Sub
Function:
Function getName(pf)
getName = Split(pf, "/")(UBound(Split(pf, "/")))
End Function
Instead of Set hDoc = MSHTML.HTMLDocument, use:
Set hDoc = CreateObject("htmlfile")
In VBA/VB6 you can specify variable and object types but not with VBScript. You have to use CreateObject (or GetObject: GetObject function) to instantiate objects like MSHTML.HTMLDocument, Microsoft.XMLHTTP, InternetExplorer.Application, etc instead of declaring those using Dim objIE As InternetExplorer.Application for example.
Another change:
If Anchor.pathname Like "*.pdf" Then
can be written using StrComp function:
If StrComp(Right(Anchor.pathname, 4), ".pdf", vbTextCompare) = 0 Then
or using InStr function:
If InStr(Anchor.pathname, ".pdf") > 0 Then
Also, at the beginning of your sub, you do the following:
Set xHttp = CreateObject("Microsoft.XMLHTTP")
Dim xHttp
You should declare your variables before assigning them values or objects. In VBScript this is very relaxed, your code will work because VBScript will create undefined variables for you but it's good practice to Dim your variables before using them.
Except for Wscript.sleep commands, your VBScript code will work in VB6/VBA so you can debug your script in VB6 or VBA apps (like Excel).

Find checkbox that tharts with id

I'm trying to loop trough a bunch of checkboxes that start with a specific id.
This bit of code seems normal, but it doesn't find anything :
Dim childc As Control
Dim c as Control
For Each c In Me.Page.Controls
For Each childc In c.Controls
If TypeOf childc Is CheckBox Then
If CType(childc, CheckBox).Checked Then
If childc.ID.StartsWith("ctl00_indexBody_ID_ACTIVITE_") Then
i = i + 1
Alerte(CType(childc, CheckBox).Text)
strSQL = "INSERT INTO A_ACTIVITES VALUES("
strSQL += Me.ID_PRESTATAIRE.Text + "," + childc.ID + ","
strSQL += ")"
oWebConnection.Execute(strSQL)
End If
End If
End If
Next
Next
it breacks in the second line saying that
it's impossible to cast an objet of type 'ASP.masterpage_master' to 'System.Web.UI.WebControls.CheckBox
Thank's for your help
Declare c and childc as Control, not CheckBox.
The declaration of c is not visible but I think you made the same mistake.
I found a solution
Protected Sub GererActivite(ByVal oControls As ControlCollection)
Dim oControl As Control
For Each oControl In oControls
If oControl.HasControls Then
GererActivite(oControl.Controls) ' récursivité
ElseIf TypeOf oControl Is CheckBox Then
If CType(oControl, CheckBox).Checked Then
If CType(oControl, CheckBox).Text.StartsWith("ctl00_indexBody_ID_ACTIVITE_") Then
End If
End If
End If
Next
End Sub
This function runs trough a control Collection, and if a control of this collection has controls, i run trough these controls with the same function untill it finds a control that hasn't controls and if it is a checkbox, i can check on it as i wish.
It worked like a charm.
In fact it's my bosses idea i'm just bragging around, lol.
Hope it will help others.

ASP.Net - Reducing repetitive code for validation - VB

I have a form with many drop down list boxes on. Each of which I am showing or hiding a row of a table based on its value then adding a requiredfieldvalidator to the text box contained in that row. I am doing this on the selectedindexchanged event of each drop down list, the code for which can be seen below:
Protected Sub cbOffCover_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbOffCover.SelectedIndexChanged
If cbOffCover.SelectedValue = "N" Then
OffCoverRow.Visible = True
Dim rfOffcover As RequiredFieldValidator = New RequiredFieldValidator
With rfOffcover
.ControlToValidate = txtOffCover.ID
.SetFocusOnError = True
.ErrorMessage = "*"
.ForeColor = System.Drawing.Color.Red
End With
OffCoverCell.Controls.Add(rfOffcover)
Else
OffCoverRow.Visible = False
Dim c As Control
For Each c In OffCoverCell.Controls
If c.ID = "rfOffCover" Then
OffCoverCell.Controls.Remove(c)
End If
Next c
End If
End Sub
I then reuse this code for each drop down list to show/hide a differently named row and apply validation to a different text box.
My question being is there a better way of doing this? I don't know exactly how but I can't help but think I don't have to write this much code (or copy/paste) over and over again for each drop down list. Is it possible to write a function/class that will do the work and I can just call that instead? Might seem basic but i'm new to asp/vb. Many thanks
You can put it in a function that returns a boolean. When you call the function, pass it the combobox itself and whatever values you want to validate against. If it matches, return true. Try something like this:
Public Function ValidateComboBox(someComboBox as ComboBox, expectedValue as String)
Dim result as Boolean = False
If someComboBox.SelectedValue = expectedValue Then
result = True
OffCoverRow.Visible = True
Dim rfOffcover As RequiredFieldValidator = New RequiredFieldValidator
With rfOffcover
.ControlToValidate = txtOffCover.ID
.SetFocusOnError = True
.ErrorMessage = "*"
.ForeColor = System.Drawing.Color.Red
End With
OffCoverCell.Controls.Add(rfOffcover)
Else
OffCoverRow.Visible = False
Dim c As Control
For Each c In OffCoverCell.Controls
If c.ID = "rfOffCover" Then
OffCoverCell.Controls.Remove(c)
End If
Next c
End If
Return result
End Function
Of course, modify it to fit your needs. Maybe you only return the value, and do the other stuff inside the control's SelectedIndexChanged method.

telerik grid edit with validators seems overlapped

i have a telerik grid for asp.net ajax with AllowAutomaticxxxx properties set to true and EditMode="EditForms".
The mastertableview is for Divisions and detail table is for functions. Currently am able to insert new division and function and also edit division and function. i am using required field validator for both divisions and functions. now am facing a problem. the validator appears as overlapped when opening one edit function and one insert division.i mean when they are opened at the same time, and when i edited the function and clicked the update button, the validator for division name appears!!
1 more thing i have used ajaxmanager for the grid and i am not sure whether this is the issue.
i solved this issue by setting validationgroup for each edit and delete like this in the itemCreated event of the grid
If TypeOf e.Item Is Telerik.Web.UI.GridEditableItem AndAlso e.Item.IsInEditMode Then
If "Divisions".Equals(e.Item.OwnerTableView.Name) Then
Dim rvDivisionName = DirectCast(e.Item.FindControl("rvDivisionName"), RequiredFieldValidator)
If TypeOf e.Item Is Telerik.Web.UI.GridEditFormInsertItem Then
rvDivisionName.ValidationGroup = "addDivisionRowValidation"
TryCast(TryCast(e.Item, Telerik.Web.UI.GridEditFormItem).FindControl("PerformInsertButton"), LinkButton).ValidationGroup = "addDivisionRowValidation"
Else
rvDivisionName.ValidationGroup = "editDivisionRowValidation"
TryCast(TryCast(e.Item, Telerik.Web.UI.GridEditFormItem).FindControl("UpdateButton"), LinkButton).ValidationGroup = "editDivisionRowValidation"
End If
ElseIf "Functions".Equals(e.Item.OwnerTableView.Name) Then
Dim rvFunctionName = DirectCast(e.Item.FindControl("rvFunctionName"), RequiredFieldValidator)
Dim rvFunctionRoleName = DirectCast(e.Item.FindControl("rvFunctionRoleName"), RequiredFieldValidator)
If TypeOf e.Item Is Telerik.Web.UI.GridEditFormInsertItem Then
rvFunctionName.ValidationGroup = "addFunctionRowValidation"
rvFunctionRoleName.ValidationGroup = "addFunctionRowValidation"
TryCast(TryCast(e.Item, Telerik.Web.UI.GridEditFormItem).FindControl("PerformInsertButton"), LinkButton).ValidationGroup = "addFunctionRowValidation"
Else
rvFunctionName.ValidationGroup = "editFunctionRowValidation"
rvFunctionRoleName.ValidationGroup = "editFunctionRowValidation"
TryCast(TryCast(e.Item, Telerik.Web.UI.GridEditFormItem).FindControl("UpdateButton"), LinkButton).ValidationGroup = "editFunctionRowValidation"
End If
End If
End If

How do I use id's of HTML elements in another sub when they are created from server-side code?

I have a table that I'm creating in code behind with the final column containing a HTML checkbox with runat="server".
The code I'm using to do this is:
Do While reader.HasRows
Do While reader.Read
Dim tNewRow As New HtmlTableRow
Dim cellSKU, cellDESCR, cellDept1, cellDeptGrp1, cellDeptRng1, cellStand, cellBoard, cellSelect As New HtmlTableCell
cellSKU.InnerHtml = "<a href='edit.aspx?edit=" & reader("SKUN") & "'>" & reader("SKUN") & "</a>"
cellDESCR.InnerText = reader("DESCR")
cellDept1.InnerText = reader("DPT1")
cellDeptGrp1.InnerText = reader("GRP1")
cellDeptRng1.InnerText = reader("RNG1")
cellBoard.InnerText = reader("BOARD")
cellStand.InnerText = reader("STAND")
cellSelect.InnerHtml = "<input type='checkbox' id='selectedSKU' value='" & reader("SKUN") & "' runat='server' />"
tNewRow.Cells.Add(cellSKU)
tNewRow.Cells.Add(cellDESCR)
tNewRow.Cells.Add(cellDept1)
tNewRow.Cells.Add(cellDeptGrp1)
tNewRow.Cells.Add(cellDeptRng1)
tNewRow.Cells.Add(cellStand)
tNewRow.Cells.Add(cellBoard)
tNewRow.Cells.Add(cellSelect)
tNewRow.Style.Add("border", "solid 1px #cccccc")
skusTable.Rows.Add(tNewRow)
Loop
reader.NextResult()
Loop
But I want to use the checkbox in another sub such as:
Protected Sub editSkus_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles editSkus.Click
End Sub
Though I can't use selectedSKU.whatever as the checkbox doesn't exist on the page until the other section of code is run.
Is there a way I can get around this or another way of doing things?
Thanks in advance for any help.
It's nasty, but here goes...
Dim skusTable As New HtmlTable
Dim i As Integer
Do While reader.HasRows
Do While reader.Read
i = i + 1
Dim tNewRow As New HtmlTableRow
tNewRow.ID = "MyRow" & i
Dim cellSKU, cellDESCR, cellDept1, cellDeptGrp1, cellDeptRng1, cellStand, cellBoard, cellSelect As New HtmlTableCell
cellSKU.InnerHtml = "<a href='edit.aspx?edit=" & reader("SKUN") & "'>" & reader("SKUN") & "</a>"
cellDESCR.InnerText = reader("DESCR")
cellDept1.InnerText = reader("DPT1")
cellDeptGrp1.InnerText = reader("GRP1")
cellDeptRng1.InnerText = reader("RNG1")
cellBoard.InnerText = reader("BOARD")
cellStand.InnerText = reader("STAND")
'Create the checkbox as a webcontrol and add it to the table cell
Dim checkBox As New HtmlControls.HtmlInputCheckBox
checkBox.Value = reader("SKUN")
checkBox.ID = "selectedSKU"
cellSelect.ID = "SelectedCell"
cellSelect.Controls.Add(New WebControls.CheckBox)
tNewRow.Cells.Add(cellSKU)
tNewRow.Cells.Add(cellDESCR)
tNewRow.Cells.Add(cellDept1)
tNewRow.Cells.Add(cellDeptGrp1)
tNewRow.Cells.Add(cellDeptRng1)
tNewRow.Cells.Add(cellStand)
tNewRow.Cells.Add(cellBoard)
tNewRow.Cells.Add(cellSelect)
tNewRow.Style.Add("border", "solid 1px #cccccc")
skusTable.Rows.Add(tNewRow)
Loop
reader.NextResult()
Loop
Now all you need do is use FindControls to get to the element...
Dim myRow As HtmlControls.HtmlTableRow = skusTable.FindControl("MyRow" & i)
'Probably be good to check the object exists first....
If Not myRow Is Nothing Then
Dim myCell As HtmlControls.HtmlTableCell = myRow.FindControl("SelectedCell")
If Not myCell Is Nothing Then
Dim myCheckbox As HtmlControls.HtmlInputCheckBox = myCell.FindControl("selectedSKU")
If Not myCheckbox Is Nothing Then
'Got it! now is it selected?
Return myCheckbox.Checked
End If
End If
End If
The runat="Server" attribute is parsed by the ASP.NET process and indicates that it should create some kind of control object. At the point your code is running this parsing has already been done. ASP.NET does not parse content added to the InnerHTML property to look for additional runat attributes or any other ASP.NET specific markup, InnerHTML is expected to be strictly standard HTML that is to be sent to the server.
You could create an instance of the CheckBox ASP.NET control and add it to the cellSelect controls collection, which is the equivalent to runat="Server". However that doesn't really help because you want to bind an event to this control but on post back this control will no longer exist.
Is there a reason you are not using DataGrid to acheive this UI?

Resources