By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,787 Members | 2,251 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,787 IT Pros & Developers. It's quick & easy.

I'd guess I can't do this

P: n/a
Given a button name Btn_5 and Index=5

I want to do something like

dim zz as string = Btn_??Index??.Text

or given an array of buttons, do:

BtnArray(4)= Btn_??Index??

Not necessarily that simply, but is there a way I can create the name of a
variable at runtime?
Thanks
Nov 21 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
For various reasons, you might not know until run time what templates you
need or what text or controls should be in them. In that case, you need to be
able to create the templates dynamically (in code).

Note: You can also create templates as Web Forms user controls and bind
them dynamically to controls on your page. For details, see Creating a
Templated User Control.
You can create templates in code for all controls that use templates: the
DataList, Repeater, and DataGrid controls. For the DataGrid control, you use
templates to define columns instead of the row-like templates for the other
two controls.

Note: There are a few differences when creating template columns for the
DataGrid control. For details, see Creating Templates Programmatically in the
DataGrid Control.
Creating the Template Class
To create dynamic templates, you create a template class that you can then
instantiate when needed.

Note: For background on creating classes in Visual Basic .NET, see
Understanding Classes. For similar information for Visual C# .NET, see class.
To create a template class

Create a new class that implements the ITemplate interface of the
System.Web.UI namespace.
Optionally, pass into the class's constructor a value that the class can use
to determine what type of template to create (ItemTemplate,
AlternatingItemTemplate, and so on).
Tip A type-safe way to pass the template type to the constructor is to add
a parameter to the constructor with the type ListItemType. The ListItemType
enumeration defines the possible template types for the Repeater, DataList,
and DataGrid controls.
In the class, implement the InstantiateIn method (the only member of the
ITemplate interface). This method provides a way to insert an instance of
text and controls into the specified container.
In the InstantiateIn method, create the controls for the template item, set
their properties, and then add them to the parent's Controls collection. You
can access the parent control via the reference passed to the InstantiateIn
method.
Note You cannot directly add static text to the Controls collection, but
you can create controls like the Literal control or the LiteralControl
control, set their Text properties, and then add those controls to the parent
collection.
The following example illustrates a complete template class that displays
some static text ("Item number:") and a counter. The counter is maintained as
a shared or static value (depending on what language you are using) called
itemcount for the class and incremented each time a new item is created.

The class defines an explicit constructor that accepts a ListItemType
enumeration value to indicate what type of template is being created.
Depending on what type of template is being created, the code creates
different types of controls and adds them to the Controls collection of the
parent control. The end result is an HTML table with a different background
color for the alternating item template.

' Visual Basic
Private Class MyTemplate
Implements ITemplate
Shared itemcount As Integer = 0
Dim TemplateType As ListItemType

Sub New(ByVal type As ListItemType)
TemplateType = type
End Sub

Sub InstantiateIn(ByVal container As Control) _
Implements ITemplate.InstantiateIn
Dim lc As New Literal()
Select Case TemplateType
Case ListItemType.Header
lc.Text = "<TABLE border=1><TR><TH>Items</TH></TR>"
Case ListItemType.Item
lc.Text = "<TR><TD>Item number: " & itemcount.ToString _
& "</TD></TR>"
Case ListItemType.AlternatingItem
lc.Text = "<TR><TD bgcolor=lightblue>Item number: " _
& itemcount.ToString & "</TD></TR>"
Case ListItemType.Footer
lc.Text = "</TABLE>"
End Select
container.Controls.Add(lc)
itemcount += 1
End Sub
End Class

// C#
public class MyTemplate : ITemplate
{
static int itemcount = 0;
ListItemType templateType;

public MyTemplate(ListItemType type)
{
templateType = type;
}

public void InstantiateIn(System.Web.UI.Control container)
{
Literal lc = new Literal();
switch( templateType )
{
case ListItemType.Header:
lc.Text = "<TABLE border=1><TR><TH>Items</TH></TR>";
break;
case ListItemType.Item:
lc.Text = "<TR><TD>Item number: " + itemcount.ToString() +
"</TD></TR>";
break;
case ListItemType.AlternatingItem:
lc.Text = "<TR><TD bgcolor=lightblue>Item number: " +
itemcount.ToString() + "</TD></TR>";
break;
case ListItemType.Footer:
lc.Text = "</TABLE>";
break;
}
container.Controls.Add(lc);
itemcount += 1;
}
}
Using the Dynamic Template
When you have a dynamic template available, you can instantiate it in code.

Note To work with a dynamic template as a column in a DataGrid control,
see Creating Templates Programmatically in the DataGrid Control.
To use a dynamic template

Create an instance of your dynamic template, passing it an item type value
if appropriate.
Assign the instance to one of the template properties of the Repeater or
DataList control: ItemTemplate, AlternatingItemTemplate, HeaderTemplate, and
so on.
The following example shows how to use the dynamic template with a Repeater
control. In this example, the templates are instantiated while the page is
being loaded and before the control is bound to its data source.

' Visual Basic
Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Repeater1.HeaderTemplate = New MyTemplate(ListItemType.Header)
Repeater1.ItemTemplate = New MyTemplate(ListItemType.Item)
Repeater1.AlternatingItemTemplate = _
New MyTemplate(ListItemType.AlternatingItem)
Repeater1.FooterTemplate = New MyTemplate(ListItemType.Footer)
SqlDataAdapter1.Fill(DsCategories1)
Repeater1.DataBind()
End Sub

// C#
private void Page_Load(object sender, System.EventArgs e)
{
Repeater1.HeaderTemplate = new MyTemplate(ListItemType.Header);
Repeater1.ItemTemplate = new MyTemplate(ListItemType.Item);
Repeater1.AlternatingItemTemplate =
new MyTemplate(ListItemType.AlternatingItem);
Repeater1.FooterTemplate = new MyTemplate(ListItemType.Footer);
sqlDataAdapter1.Fill(dsCategories1);
Repeater1.DataBind();
}
Adding Data Binding to Templates
There are various ways to get access to data from within a template class,
depending on how you have created the class. A good way is one in which the
page architecture itself implements data binding — when you add controls to
the template, you also add a handler for their DataBinding event. This event
will be raised after the template item has been created with all its
controls, and it provides you with an opportunity to fetch data and use it in
a control.

Note You cannot embed a data-binding expression as a string when creating
controls in the template, as you do when defining templates at design time,
because data-binding expressions are converted into code at a stage of page
processing that occurs before your template is created.
In the handler for the DataBinding event, you have an opportunity to
manipulate the contents of the control. Typically (but not necessarily), you
fetch data from somewhere and assign it to the control's Text property.

Note For background on data binding in Web Forms pages, see Web Forms Data
Binding.
To add data binding to a dynamic template, you must do the following:

Add a data-binding event handler to the controls you create in the template.
Create the handler that you are binding to. In the handler, get the data
that you want to bind to and assign it to the appropriate property of the
control being bound.
To add the data-binding event handler

After creating a control in the dynamic template, use standard commands to
bind the control's DataBinding event to a method that you will create later.
Note For details on how to add event handlers dynamically, see AddHandler
and RemoveHandler (for Visual Basic) and Events Tutorial (for Visual C#).
The following example shows code from the template class illustrating how
you can bind a newly created control to a method called
TemplateControl_DataBinding.

' Visual Basic
Dim lc As New Literal()
Case ListItemType.Item
lc.Text = "<TR><TD>"
AddHandler lc.DataBinding, AddressOf TemplateControl_DataBinding

// C#
Literal lc = new Literal();
case ListItemType.Item:
lc.Text = "<TR><TD>";
lc.DataBinding += new EventHandler(TemplateControl_DataBinding);
break;
Note that in this example, the text you add to the literal control's Text
property is different than in the previous example. It contains only the
beginning of the table row and cell for the item template. You will complete
the cell and row in the data-binding event handler.

The next step is to create the event handler that will be called when the
control is data bound.

To create the handler for the DataBinding event

Create a method that is part of your template class as a peer of the class's
other methods (such as InstantiateIn). The handler's name must match the name
you used when binding the event earlier. The method should have the following
signature:
' Visual Basic
Private Sub TemplateControl_DataBinding(ByVal sender As Object, _
ByVal e As System.EventArgs)

// C#
private void TemplateControl_DataBinding(object sender,
System.EventArgs e)
Get a reference to the DataItem object containing the data for the current
template item, by doing the following:
Get a reference to the template item. You create a variable to hold the
reference and then assign it the value you get from your control's
NamingContainer property.
Use that reference to get the naming container's (the template item's)
DataItem property.
Extract the individual data element (data column, for example) from the
DataItem object and use it to set a property of the control you are binding.
The following code illustrates one way to perform data binding within a
dynamic template. It shows a complete data-binding event handler for Literal
controls being created in a template for a Repeater control.

' Visual Basic
Private Sub TemplateControl_DataBinding(ByVal sender As Object, _
ByVal e As System.EventArgs)
Dim lc As Literal
lc = CType(sender, Literal)
Dim container As RepeaterItem
container = CType(lc.NamingContainer, RepeaterItem)
lc.Text &= DataBinder.Eval(container.DataItem, "CategoryName")
lc.Text &= "</TD></TR>"
End Sub

// C#
private void TemplateControl_DataBinding(object sender,
System.EventArgs e)
{
Literal lc;
lc = (Literal) sender;
RepeaterItem container = (RepeaterItem) lc.NamingContainer;
lc.Text += DataBinder.Eval(container.DataItem, "CategoryName");
lc.Text += "</TD></TR>";
}
Note If you have multiple types of controls in your templates, you would
need to create a different data-binding event handler for each of the control
types

"Just Me" wrote:
Given a button name Btn_5 and Index=5

I want to do something like

dim zz as string = Btn_??Index??.Text

or given an array of buttons, do:

BtnArray(4)= Btn_??Index??

Not necessarily that simply, but is there a way I can create the name of a
variable at runtime?
Thanks

Nov 21 '05 #2

P: n/a
Hallo,

I do not know what you are after, however you can set your controls in an
array of any style.
By instance a normal array just with
dim ctrArr() as control = new Control() {myButton1, myButton2, myButton3}
However as well any other array or collection.
mystring = ctrArr(x).text
'in the case of text casting is not needed because it is a property which
button derives from control.

I hope this gives some ideas?

Cor
Nov 21 '05 #3

P: n/a
* " Just Me" <ne********@a-znet.com> scripsit:
Given a button name Btn_5 and Index=5

I want to do something like

dim zz as string = Btn_??Index??.Text

or given an array of buttons, do:

BtnArray(4)= Btn_??Index??

Not necessarily that simply, but is there a way I can create the name of a
variable at runtime?


\\\
Private Function FindControl( _
ByVal ControlName As String, _
ByVal CurrentControl As Control _
) As Control
Dim ctr As Control
For Each ctr In CurrentControl.Controls
If ctr.Name = ControlName Then
Return ctr
Else
ctr = FindControl(ControlName, ctr)
If Not ctr Is Nothing Then
Return ctr
End If
End If
Next ctr
End Function
///

Usage:

\\\
DirectCast(FindControl("Button1", Me), Button).Enabled = False
///

Notice that the procedure listed above is "slow", if you have to access a
lot of controls by name very often, you should store references to them in a
'Hashtable' object. You can use the name of the control as key:

\\\
Private m_Controls As New Hashtable()
///

Adding a control:

\\\
Dim DynamicPictureBox As New PictureBox()
DynamicPictureBox.Name = "PictureBox1"
m_Controls.Add(DynamicPictureBox.Name, DynamicPictureBox)
///

Looking for a control:

\\\
Dim p As PictureBox = DirectCast(m_Controls.Item("PictureBox1"), PictureBox)
///

Removing a control:

\\\
m_Controls.Remove("PictureBox1")
///

Sometimes it's even better to add the control to an array. This will allow
fast and easy index-based access to the control references:

\\\
Dim MyLabels() As Label = {Label1, Label2, ..., Label10}
///

Access by 'MyLabels(0)' to 'MyLabels(9)'.

Control arrays:

Control arrays, as known from VB6, are not included in VB.NET 2002/2003.

Creating Control Arrays in Visual Basic .NET and Visual C# .NET:
<URL:http://msdn.microsoft.com/library/en-us/dv_vstechart/html/vbtchCreatingControlArraysInVisualBasicNETVisualCN ET.asp>

WinForms Controls--Creating Control Arrays in VB.NET
<URL:http://www.devx.com/vb2themax/Article/19907/>

--
Herfried K. Wagner [MVP]
<URL:http://dotnet.mvps.org/>
Nov 21 '05 #4

P: n/a
I should have presented the underlining problem instead.

I have maybe a hundred controls generated by conversion from VB6.

Named like btn_0, btn_1,...

I'd like to put then into an VB.NET array of Buttons but don't like the idea
of doing

ButtonArray(0)= btn_0
ButtonArray(1)=btn_1
..
..
..

Looks like I could adapt Herfried's Find Control method and, in fact, I'm
going to start right now.

But I thought I'd pass along a better description of the problem while I'm
saying thanks for the three replies.

THANKS
" Just Me" <ne********@a-znet.com> wrote in message
news:%2***************@tk2msftngp13.phx.gbl...
Given a button name Btn_5 and Index=5

I want to do something like

dim zz as string = Btn_??Index??.Text

or given an array of buttons, do:

BtnArray(4)= Btn_??Index??

Not necessarily that simply, but is there a way I can create the name of a variable at runtime?
Thanks

Nov 21 '05 #5

P: n/a
Can't believe how easy it was to get rid of a VB6 compatability Button array
using FindControl.
After deleting the VB6 array code I think I ended up with less total lines
of code.

For lLpCnt = 0 To 33

mPadButtonArray(lLpCnt) = Utility.FindControl("PadButton_" & CStr(lLpCnt),
Me)

mPadButtonArray(lLpCnt).Tag = lLpCnt 'Use Tag instead of GetIndex

AddHandler mPadButtonArray(lLpCnt).Click, AddressOf PadButton_Click

Next

Now I have to repeat for the other VB6 arrays.

Thanks


" Just Me" <ne********@a-znet.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
I should have presented the underlining problem instead.

I have maybe a hundred controls generated by conversion from VB6.

Named like btn_0, btn_1,...

I'd like to put then into an VB.NET array of Buttons but don't like the idea of doing

ButtonArray(0)= btn_0
ButtonArray(1)=btn_1
.
.
.

Looks like I could adapt Herfried's Find Control method and, in fact, I'm
going to start right now.

But I thought I'd pass along a better description of the problem while I'm
saying thanks for the three replies.

THANKS
" Just Me" <ne********@a-znet.com> wrote in message
news:%2***************@tk2msftngp13.phx.gbl...
Given a button name Btn_5 and Index=5

I want to do something like

dim zz as string = Btn_??Index??.Text

or given an array of buttons, do:

BtnArray(4)= Btn_??Index??

Not necessarily that simply, but is there a way I can create the name
of a
variable at runtime?
Thanks


Nov 21 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.