How to modify property of radiobutton without using its id tag - asp.net

I need to go through a loop and check the proper radiobutton. I have multiple radio button named rb with a color such as "rbGreen, rbRed, rbYellow..."
Here is my code behind: (listColors is a list of strings)
Private Sub selectColor(color As String)
Dim i As Integer
For i = 0 To listColors.Count - 1
If listColors(i) = color Then
Dim rb As RadioButton = TryCast(Page.FindControl("rb" & color), RadioButton)
rb.Checked = True
End If
Next i
End Sub
While debugging, I got an error because rb is nothing...

My guess is that the RadioButtons in question are not actually part of the Page, and are instead part of a UserControl or template based control (such as a Repeater).
If so, then you need to modify your code to use the FindControl of the control that holds the RadioButtons in question.
If this is within a UserControl the easiest thing to do is something like...
Me.FindControl("rb" & color)

Related

Creating a New control of the same type as another control that is already declared

I'm using a custom template class to generate lines with my repeater control, i'd like to be able to specify the controls in this repeater dynamically from the code behind my aspx page.
In the code behind I've added controls to a list like this:
Dim lstControls As New List(Of Control)
lstControls.Add(New TextBox)
lstControls.Add(New Label)
lstControls.Add(New CheckBox)
lstControls.Add(New DropDownList)
lstControls.Add(New CheckBox)
Then i use this line to add the controls to my template
rptrSummary.ItemTemplate = New myTemplate(ListItemType.Item, , lstControls)
From the instantiateIn sub i'm doing something like this:
Dim ph As New PlaceHolder
For i = 0 To lstControls.Count - 1
ph.Controls.Add(lstControls(i))
Next
This doesn't work properly and following .databind() of my repeater control the controls i specify only appear on the final row. I think this is because i've only declared the controls as NEW once, so i only have one rows worth.
tldr?/ conclusion:
How can i generate new controls of the same type as controls from my list? Something like:
Dim newControl as new Control = type(lstControl(0))
(this obviously doesn't work)
I've found the answer, here are some examples in case anyone else is stuck (i may also change the title so it's more similar to likely search criteria):
dim egTextbox as new textbox
dim egLabel as new label
dim newObject1 as Object = Activator.CreateInstance(egTextbox.GetType)
dim newObject2 as Object = Activator.CreateInstance(egLabel.GetType)
newObject1 is now a textbox
newObject2 is now a label

Dynamically Adding Multiple User Controls vb.net

I have a User Control which returns a table of data, which in some cases needs to be looped, displaying one on top of another.
I am able to dynamically add a single instance of this by placing a fixed placeholder in the page.
I am now trying to work out how to add more than one, given that I don't know how many might be needed I don't want to hard code the Placeholders.
I've tried the following, but I am just getting one instance, presumably the first is being overwritten by the second
My HTML
<div id="showHere" runt="server"/>
VB
Dim thisPh As New PlaceHolder
thisPh.Controls.Add(showTable)
showHere.Controls.Add(thisPh)
Dim anotherPh As New PlaceHolder
anotherPh .Controls.Add(showTable)
showHere.Controls.Add(anotherPh)
How do I make it add repeated tables within the showHere div?
I would advise generating a different ID for each of your table. For example,
Dim i As Integer
i = 0
For each tbl in ShowTables
tbl.ID = "MyTab" + i.ToString()
i = i + 1
showHere.Controls.Add(tbl)
showHere.Controls.Add(New LiteralControl("<br />"))
Next
On other hand, it would make more sense to have a your user/custom control generate html for a single table and then nest your user/custom control within a repeater (or similar control such as ListView etc).
Did you tried simply, this:
For each tbl in ShowTables
showHere.Controls.Add(tbl)
showHere.Controls.Add(New LiteralControl("<br />"))
Next
After fussing with this issue myself, I stumbled across below solution.
On button click()
LocationDiv.Visible = True
Dim existingItems As New List(Of Object)
If Not Session("existingItems") Is Nothing Then
existingItems = CType(Session("existingItems"), List(Of Object))
For Each item As Object In existingItems
LocationDiv.Controls.Add(item)
Next
existingItems.Clear()
End If
LocationDiv.Controls.Add(New LiteralControl("<b>" & Text & "</b>"))
For Each item As Object In LocationDiv.Controls
existingItems.Add(item)
Next
Session.Add("existingItems", existingItems)

accessing HtmlTable inside a placeHolder

I'm working with a website written in aspx.net over vb.
I have a placeHolder, and I create a table of names inside this PlaceHolder, each name has an HtmlInputCheckBox next to it.
Im doing this in the aspx.vb file, when the page is uploading.
Then, when the user wants to send mail, he presses a button and than I need to access the checkboxes, and I'm having problems with this, the Sub doesn't know the checkBox object.
I would love for some help,
Thank you!
I understand that you're creating those checkboxes dynamically?
In such case, store them as global member of the class, most simple way is to have List of them:
List<HtmlInputCheckBox> arrCheckboxes = new List<HtmlInputCheckBox>();
...
...
HtmlInputCheckBox myCheckbox = new HtmlInputCheckBox();
arrCheckboxes.Add(myCheckbox);
...
This is C# but should be easy to translate to VB - anyhow having this, you can access the List and it should work.
Worst case as "last resort" you can simply iterate the whole Request.Form collection and look for Keys with name matching to the checkbox name.
Put this in the procedure...
Dim chkValue1 As New CheckBox
Dim chkValue2 As New CheckBox
'Find the Checkbox Controls in the PlaceHolder and cast them to the checkboxes we just made.
chkValue1 = CType(YourPlaceHolder.FindControl("Checkbox1ControlId"), CheckBox)
chkValue2 = CType(YourPlaceHolder.FindControl("Checkbox2ControlId"), CheckBox)
'Now you can do this...
Dim bolIsValue1Checked As Boolean = chkValue1.Checked

dynamically set control ID

i have few texboxt and dropdownlist, which their id would be something like "txtName1, txtName2, txtName3..." and "ddlAction1, ddlAction2, ddlAction3...."! I would to to dynamically set the textboxt and dropdownlist id into something like this:
for i as integer = 0 to 6
a = txtName+i.text
b = ddlAction+i.SelectedValue
next i
Need help from you guys to do this! thanks....
The key is FindControl, which looks up a control by its expected ID:
For i As Integer = 0 To 5
Dim txt As TextBox = TryCast(Me.Page.FindControl("txtName" & i.ToString()), TextBox)
Dim ddl As DropDownList = TryCast(Me.Page.FindControl("ddlAction" & i.ToString()), DropDownList)
If txt IsNot Nothing AndAlso ddl IsNot Nothing Then
Dim a As String = txt.Text
Dim b As String = ddl.SelectedValue
End If
Next
It will return null/nothing if a control with that ID isn't found.
Note that FindControl will only search the given control's (or Page's) immediate children, not the entire control tree. To search recursively, you need to use your own FindControl method.
Private Function FindControlRecursive(ByVal control As Control, ByVal id As String) As Control
Dim returnControl As Control = control.FindControl(id)
If returnControl Is Nothing Then
For Each child As Control In control.Controls
returnControl = child.FindControlRecursive(id)
If returnControl IsNot Nothing AndAlso returnControl.ID = id Then
Return returnControl
End If
Next
End If
Return returnControl
End Function
.Net requires you to resolve your variable names at compile time, rather than runtime like your code is trying to do. This is a good thing, as it prevents you from making certain kinds of errors. But it does mean you'll need to look at an alternative approach for this particular problem.
One option is a FindControl -based method. But odds are the controls you care about are grouped together on the page. If they aren't already, put them in a common container control, like a panel. Then you can do something like this (requires System.Linq):
For Each t As TextBox In MyContainer.Controls.OfType(Of TextBox)()
a = t.Text
Next t
For Each d As DropDownList In MyContainer.Controls.OfType(Of DropDownList)()
b = d.SelectedValue
Next d
Also, I hope you're really doing something other than assignment inside your loop. Otherwise, most of the work is for nothing as you will exit the loop having simply assigned the value from the last iteration to your variable.
Finally, it seems like these controls might work in pairs. To me, that's a situation that calls out for you to implement a user control.
I'm not a webforms expert, but I believe the page stores a reference to each control present in the page.
You can think of webforms like an n-ary tree... each control has a parent and can have 0 to many children. So, if these are static controls you should just be able to grab a reference to their parent and iterate over that... with no need for the children's ids.
Also, you can query for children based on their id... something like myControl["myID1"] so you can concat the number with the string and get the control that way.
Lastly, if these are purely dynamic controls, i.e. you don't know how many there are, just store references to them in an ordered collection and iterate over them that way.
EDIT:
Here we go:
WebControl myControl;
myControl.Controls.Add(someControlReference);
Then, to grab a control by ID:
WebControl someControl = myControl.FindControl("someControlID1");
From there you can do like:
string a = someControl.Text

Inheriting DropDownList and adding custom values using its DataSourceObject

I'm inheriting a DropDownList to add two custom ListItems. The first item is "Select one..." and the second item gets added at the end, it's value is "Custom".
I override DataBind and use the following code:
Dim data As List(Of ListItem) = CType(DataSource, List(Of ListItem))
data.Insert(0, New ListItem("Select one...", SelectOneListItemValue))
If DisplayCustomOption Then
data.Insert(data.Count, New ListItem("Custom", CustomListItemValue))
End If
DataSource = data
MyBase.DataBind()
The problem is this code won't work if the DataSource is anything other than a List of ListItem. Is there a better way of doing this?
You could make the assumption that the data source always inherits IList, in which case you could do the following:
Dim data As IList = CType(DataSource, IList)
data.Insert(0, New ListItem("Select one...", SelectOneListItemValue))
' And so on...
Of course, this assumes that whatever the data source is, it allows you to add objects of the type ListItem. But this might be generic enough for what you need.
You could just leave the databind alone and add your special Items in the DataBound event handler.
Protected Sub MyDropDownList_DataBound(sender As Object, e As EventArgs) _
Handles MyDropDownList.DataBound
MyBase.Items.Insert(0, New ListItem("Select One...", SelectOneListItemValue))
If DisplayCustomOption Then
MyBase.Add(New ListItem("Custom", Custom))
End If
End Sub
(My VB.NET is limited, so you may need to adjust syntax)

Resources