Link to home
Start Free TrialLog in
Avatar of urbnsurfr
urbnsurfr

asked on

More on dynamically creating controls in VB.net

Hi, I am new to VB.net development.  I am a moderately proficient programmer in Classic ASP.

In my classic ASP world, we have done a lot of work creating dynamic pages with control-specific settings (whether the control is present, editable, and a text box or combo box or whatever) that come out of databases and XML files.  I think we want to continue that approach in VB.net (you don't always know how many detail records will need to be editable at one time).

Therefore, I was reading this topic which seems relevant for getting started:
https://www.experts-exchange.com/questions/20717399/ASP-NET-ViewState-and-dynamically-created-controls.html
It references this topic:
http://www.codeproject.com/aspnet/RetainingState.asp

I converted the code to VB.net, and added a button control which calls the AddSomeControl method:
 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        AddSomeControl()

    End Sub

When I attempt to run the solution, I get this error:
Server Error in '/TestWebApp' Application.
--------------------------------------------------------------------------------

Control 'ControlID_0' of type 'TextBox' must be placed inside a form tag with runat=server.

I have checked the HTML source design of the web form I am using and it most definitely is a runat=server.

Can you help me understand my error?  Thanks in advance!

In case it helps, this is the full code of my page:



Public Class WebForm1
    Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub
    Protected WithEvents Button1 As System.Web.UI.WebControls.Button
    Protected WithEvents TextBox1 As System.Web.UI.WebControls.TextBox

    'NOTE: The following placeholder declaration is required by the Web Form Designer.
    'Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Put user code to initialize the page here
        If (Page.IsPostBack) Then
            '//Controls must be repeatedly be created on postback
            'Me.createcontrols()
        Else
            '//Initiate the counter of dynamically added controls
            Me.NumberOfControls = 0
        End If
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        AddSomeControl()

    End Sub
    Private Property NumberOfControls()
        Get
            Return CInt(viewstate("NumControls"))

        End Get
        Set(ByVal Value)
            ViewState("NumControls") = Value
        End Set
    End Property

    Private Sub CreateControls()
        Dim count As Integer = Me.NumberOfControls
        Dim i As Integer
        Dim tx As TextBox
        For i = 1 To count
            tx = New TextBox
            tx.ID = "ControlID_" + i.ToString
            '//Add the Controls to the container of your choice
            Page.Controls.Add(tx)
        Next

    End Sub

    Private Sub AddSomeControl()
        Dim tx As TextBox = New TextBox
        tx.ID = "ControlID_" + Me.NumberOfControls.ToString
        Page.Controls.Add(tx)
        Me.NumberOfControls = Me.NumberOfControls + 1


    End Sub
End Class
Avatar of Irmawaty
Irmawaty

Have you checked if the control is inside the form tag in HTML code?
In your page your page you'll see a bunch of HTML...right inside the body tag put a form tag like so:

<form runat="server">


</form>

You can't just write out controls unless you have a form that is processed at the server. That seems to be the error.
try something like this

Private Sub AddSomeControl()
        Dim tx As TextBox = New TextBox
        tx.ID = "ControlID_" + Me.NumberOfControls.ToString
        'Page.Controls.Add(tx)
        tx.Text = "Hello Mom"
        Me.FindControl("form1").Controls.Add(tx)
        Me.NumberOfControls = Me.NumberOfControls + 1


    End Sub
ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Good idea Bob, you would do that like so:

<script runat="server">
   Sub Page_Load
       Dim txt as New TextBox
       txt.ID = "txtNew"
       txt.Text = "Hello World"
       holder.Controls.Add(txt)
       'or this
       holder.Controls.Add(New LiteralControl("<b>This is just some plain old bolded text that was dynamically added using ASP.NET</b>"))
   End Sub
</script>

<form runat="server">
     <asp:PlaceHolder ID="holder" Runat="Server"/>
</form>
Avatar of urbnsurfr

ASKER

Now I have the task of figuring out how to do control placement, but this gave me a place to start and also the right questions to be feeding into my MSDN library search.  Right off the bat, I found some topics about creating controls dynamically once I knew to look for the placeholder control.

Thanks very much!
Dave Smith

PS:  In case someone is looking for the full solution:

Public Class WebForm1
    Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub
    Protected WithEvents Button1 As System.Web.UI.WebControls.Button
    Protected WithEvents TextBox1 As System.Web.UI.WebControls.TextBox
    Protected WithEvents PlaceHolder1 As System.Web.UI.WebControls.PlaceHolder

    'NOTE: The following placeholder declaration is required by the Web Form Designer.
    'Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Put user code to initialize the page here
        If (Page.IsPostBack) Then
            '//Controls must be repeatedly be created on postback
            Me.CreateControls()
        Else
            '//Initiate the counter of dynamically added controls
            Me.NumberOfControls = 0
        End If
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        AddSomeControl()

    End Sub
    Private Property NumberOfControls()
        Get
            Return CInt(viewstate("NumControls"))

        End Get
        Set(ByVal Value)
            ViewState("NumControls") = Value
        End Set
    End Property

    Private Sub CreateControls()
        Dim count As Integer = Me.NumberOfControls
        Dim i As Integer
        Dim tx As TextBox
        For i = 1 To count
            tx = New TextBox
            tx.ID = "ControlID_" + i.ToString
            '//Add the Controls to the container of your choice
            'Page.Controls.Add(tx)
            PlaceHolder1.Controls.Add(tx)
        Next

    End Sub

    Private Sub AddSomeControl()
        Dim tx As TextBox = New TextBox
        'Dim PH As PlaceHolder = New PlaceHolder
        'PH.ID = "PlaceHolder_" & Me.NumberOfControls.ToString
        'Me.Controls.Add(PH)
        tx.ID = "ControlID_" + Me.NumberOfControls.ToString
        PlaceHolder1.Controls.Add(tx)

        'Page.Controls.Add(tx)
        Me.NumberOfControls = Me.NumberOfControls + 1

    End Sub

    Private Sub SqlConnection1_InfoMessage(ByVal sender As System.Object, ByVal e As System.Data.SqlClient.SqlInfoMessageEventArgs)

    End Sub
End Class


And the form:

<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="TestWebApp.WebForm1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
      <HEAD>
            <title>WebForm1</title>
            <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
            <meta content="Visual Basic .NET 7.1" name="CODE_LANGUAGE">
            <meta content="JavaScript" name="vs_defaultClientScript">
            <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
      </HEAD>
      <body MS_POSITIONING="GridLayout">
            <form id="Form1" method="post" runat="server">
                  <asp:button id="Button1" style="Z-INDEX: 101; LEFT: 416px; POSITION: absolute; TOP: 104px" runat="server"
                        Text="Button"></asp:button><asp:textbox id="TextBox1" style="Z-INDEX: 102; LEFT: 376px; POSITION: absolute; TOP: 32px" runat="server"
                        Width="168px" Height="48px"></asp:textbox>
                  <asp:PlaceHolder id="PlaceHolder1" runat="server"></asp:PlaceHolder></form>
      </body>
</HTML>