2012-08-17 56 views
0

我有一个窗体,其值为1-10的下拉列表的面板。当面板上的按钮被按下时,该面板变得不可见,而另一面变得可见。在第二个面板上,我有一些动态生成的控件。行数由下拉列表中的selecteditem决定。在回发期间保留动态创建的控件 - VB.net

我的问题是,当我想要进行验证,然后存储动态创建的控件内容的值时,控件将被删除。

我明白这是关于页面的生命周期和动态创建的控件的持久性,但我不知道绕开这个问题。我已经阅读了许多其他类似的问题,很少有人能够解决这个问题的实例,所以我并不聪明。这包括建议动态创建的控件需要在页面加载或pageinit上创建,这怎么可能,因为我们不知道要做多少?

任何帮助一如既往,非常感谢。

Imports DotNetNuke.Entities.Modules 
Imports DotNetNuke 
Imports System 
Imports System.Web.UI 
Imports System.Web.UI.WebControls 
Imports System.Collections.Generic 
Imports System.Reflection 
Imports System.Web.Configuration 
Imports System.Net.Mail 
Imports System.Data.SqlClient 

Partial Class View 
Inherits SeatPlannerModuleBase 
Implements IActionable 
Dim valid As String = "success" 

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load, Me.Load 
    Try 

     If Not Page.IsPostBack Then 

     End If 

    Catch exc As Exception  'Module failed to load 
     ProcessModuleLoadException(Me, exc) 
    End Try 
End Sub 

Public ReadOnly Property ModuleActions() As Entities.Modules.Actions.ModuleActionCollection Implements Entities.Modules.IActionable.ModuleActions 
    Get 
     Dim Actions As New Entities.Modules.Actions.ModuleActionCollection 
     Actions.Add(GetNextActionID, Localization.GetString(Entities.Modules.Actions.ModuleActionType.AddContent, LocalResourceFile), Entities.Modules.Actions.ModuleActionType.AddContent, "", "", EditUrl(), False, DotNetNuke.Security.SecurityAccessLevel.Edit, True, False) 
     Return Actions 
    End Get 
End Property 

Protected Sub Filldata() 
    Dim conn As New SqlConnection() 
    conn.ConnectionString = WebConfigurationManager.ConnectionStrings("Congress_SeatPlanner_ConnectionString").ConnectionString 
    Dim Qstr As String = "select * From [Seat_planner_2013].[dbo].[booking]" 
    Try 
     Using connection As New SqlConnection(conn.ConnectionString) 
      connection.Open() 
      Dim command As New SqlCommand(Qstr, connection) 
      Dim reader As SqlDataReader = command.ExecuteReader() 
      If reader.Read() Then 
       Try 
        Dim title As String 

        title = reader("title") 
        title = title.Trim 
        title_Txt.Text = title 
       Catch 
        title_Txt.Text = "" 
       End Try 
       Try 
        first_name_Txt.Text = reader("first_name") 
       Catch 
        first_name_Txt.Text = "" 
       End Try 
       Try 
        surname_Txt.Text = reader("surname") 
       Catch 
        surname_Txt.Text = "" 
       End Try 
       Try 
        company_name_Txt.Text = reader("company_name") 
       Catch 
        company_name_Txt.Text = "" 
       End Try 
       Try 
        contact_number_Txt.Text = reader("contact_phone") 
       Catch 
        contact_number_Txt.Text = "" 
       End Try 
       Try 
        contact_email_Txt.Text = reader("contact_email") 
       Catch 
        contact_email_Txt.Text = "" 
       End Try 
       Try 
        number_of_tickets_Ddl.SelectedValue = reader("number_of_tickets") 
       Catch 
        number_of_tickets_Ddl.SelectedValue = "" 
       End Try 
       Try 
        purchase_date_Txt.Text = reader("date_of_purchase") 
       Catch 
        purchase_date_Txt.Text = "" 
       End Try 
      End If 
     End Using 
    Catch ex As Exception 
     ErrLabel_Lbl.Visible = True 
     ErrLabel_Lbl.Text = ex.Message.ToString 
    End Try 
End Sub 

Protected Sub validate() 

    If title_Txt.Text.Length < 2 Then 
     title_error_Lbl.Text = "Please enter a title" 
     valid = "fail" 
    Else 
     title_error_Lbl.Text = "*" 
    End If 
    If first_name_Txt.Text.Length < 1 Then 
     first_name_error_Lbl.Text = "Please enter a first name" 
     valid = "fail" 
    Else 
     first_name_error_Lbl.Text = "*" 
    End If 
    If surname_Txt.Text.Length < 1 Then 
     surname_error_Lbl.Text = "Please enter a surname" 
     valid = "fail" 
    Else 
     surname_error_Lbl.Text = "*" 
    End If 
    If company_name_Txt.Text.Length < 1 Then 
     comnpany_name_error_Lbl.Text = "Please enter a company name" 
     valid = "fail" 
    Else 
     comnpany_name_error_Lbl.Text = "*" 
    End If 
    If contact_email_Txt.Text.Length < 1 Then 
     contact_email_error_Lbl.Text = "Please enter a contact email address" 
     valid = "fail" 
    Else 
     contact_email_error_Lbl.Text = "*" 
    End If 
    If contact_number_Txt.Text.Length < 1 Then 
     contact_phone_error_Lbl.Text = "Please enter a contact phone number" 
     valid = "fail" 
    Else 
     contact_phone_error_Lbl.Text = "*" 
    End If 
    If number_of_tickets_Ddl.SelectedValue = "Please select" Then 
     number_of_tickets_error_Lbl.Text = "Please select a number of tickets to allocate" 
     valid = "fail" 
    Else 
     number_of_tickets_error_Lbl.Text = "*" 
    End If 
    If purchase_date_Txt.Text.Length < 1 Then 
     date_of_purchase_error_Lbl.Text = "Please enter the date you purchased the tickets" 
     valid = "fail" 
    Else 
     date_of_purchase_error_Lbl.Text = "*" 
    End If 

    If valid = "fail" Then 
     ErrLabel_Lbl.Text = "Failed validation" 
    Else 
     ErrLabel_Lbl.Text = "Validation succeeded" 
    End If 

End Sub 

Protected Sub validate_step2() 

'validation here that doesn't work due to the postback issue 

End Sub 

Protected Sub IterateThroughTitle(ByVal parent As Control) 
    Dim count As Integer = 1 

    For Each c As Control In title_Placeholder.Controls 
     If c.[GetType]().ToString().Equals("System.Web.UI.WebControls.TextBox") AndAlso c.ID Is Nothing Then 
      'DirectCast(c, TextBox).Text = "TextBox_Title " + count.ToString() 
      DirectCast(c, TextBox).ID = "TextBox_Title_" + count.ToString() 
      DirectCast(c, TextBox).CssClass = "DYN_TextBox" 
      count += 1 
     End If 

     If c.Controls.Count > 0 Then 
      IterateThroughTitle(c) 
     End If 
    Next 
End Sub 

Protected Sub IterateThroughFirstname(ByVal parent As Control) 
    Dim count As Integer = 1 

    For Each c As Control In firstname_Placeholder.Controls 
     If c.[GetType]().ToString().Equals("System.Web.UI.WebControls.TextBox") AndAlso c.ID Is Nothing Then 
      'DirectCast(c, TextBox).Text = "TextBox_Firstname " + count.ToString() 
      DirectCast(c, TextBox).ID = "TextBox_Firstname_" + count.ToString() 
      DirectCast(c, TextBox).CssClass = "DYN_TextBox" 
      count += 1 
     End If 

     If c.Controls.Count > 0 Then 
      IterateThroughFirstname(c) 
     End If 
    Next 
End Sub 

Protected Sub IterateThroughSurname(ByVal parent As Control) 
    Dim count As Integer = 1 

    For Each c As Control In surname_Placeholder.Controls 
     If c.[GetType]().ToString().Equals("System.Web.UI.WebControls.TextBox") AndAlso c.ID Is Nothing Then 
      'DirectCast(c, TextBox).Text = "TextBox_Surname " + count.ToString() 
      DirectCast(c, TextBox).ID = "TextBox_Surname_" + count.ToString() 
      DirectCast(c, TextBox).CssClass = "DYN_TextBox" 
      count += 1 
     End If 

     If c.Controls.Count > 0 Then 
      IterateThroughSurname(c) 
     End If 
    Next 
End Sub 

Protected Sub IterateThroughTicketNum(ByVal parent As Control) 
    Dim count As Integer = 1 

    For Each c As Control In ticketNum_Placeholder.Controls 
     If c.[GetType]().ToString().Equals("System.Web.UI.WebControls.TextBox") AndAlso c.ID Is Nothing Then 
      'DirectCast(c, TextBox).Text = "TextBox_TicketNum " + count.ToString() 
      DirectCast(c, TextBox).ID = "TextBox_TicketNum_" + count.ToString() 
      DirectCast(c, TextBox).CssClass = "DYN_TextBox" 
      count += 1 
     End If 

     If c.Controls.Count > 0 Then 
      IterateThroughTicketNum(c) 
     End If 
    Next 
End Sub 

Protected Sub IterateThroughBooking(ByVal parent As Control) 
    Dim count As Integer = 1 

    For Each c As Control In booking_Placeholder.Controls 
     If c.[GetType]().ToString().Equals("System.Web.UI.WebControls.Label") AndAlso c.ID Is Nothing Then 
      DirectCast(c, Label).Text = "Booking #" + count.ToString() 
      DirectCast(c, Label).ID = "BookLabel_" + count.ToString() 
      DirectCast(c, Label).CssClass = "DYN_Label" 
      count += 1 
     End If 

     If c.Controls.Count > 0 Then 
      IterateThroughBooking(c) 
     End If 
    Next 
End Sub 

Protected Sub IterateThroughReservation(ByVal parent As Control) 
    Dim count As Integer = 1 

    For Each c As Control In res_Placeholder.Controls 
     If c.[GetType]().ToString().Equals("System.Web.UI.WebControls.Label") AndAlso c.ID Is Nothing Then 
      DirectCast(c, Label).Text = "Guest" 
      DirectCast(c, Label).ID = "ResLabel_" + count.ToString() 
      DirectCast(c, Label).CssClass = "DYN_Label" 
      count += 1 
     End If 

     If c.Controls.Count > 0 Then 
      IterateThroughReservation(c) 
     End If 
    Next 
End Sub 

Protected Sub Retreive_first_row() 

    CType(Me.FindControl("ResLabel_1"), Label).Text() = "You" 
    CType(Me.FindControl("TextBox_Title_1"), TextBox).Text() = title_Txt.Text 
    CType(Me.FindControl("TextBox_Title_1"), TextBox).Enabled() = False 
    CType(Me.FindControl("TextBox_Firstname_1"), TextBox).Text() = first_name_Txt.Text 
    CType(Me.FindControl("TextBox_Firstname_1"), TextBox).Enabled() = False 
    CType(Me.FindControl("TextBox_Surname_1"), TextBox).Text() = surname_Txt.Text 
    CType(Me.FindControl("TextBox_Surname_1"), TextBox).Enabled() = False 

End Sub 

Protected Sub CreateTextBoxes() 

    If Not Page.IsValid Then 
     Return 
    End If 

    Dim n As Integer = number_of_tickets_Ddl.SelectedValue 

    For i As Integer = 0 To n - 1 
     res_Placeholder.Controls.Add(New Label()) 
     booking_Placeholder.Controls.Add(New Label()) 

     title_Placeholder.Controls.Add(New TextBox()) 
     firstname_Placeholder.Controls.Add(New TextBox()) 
     surname_Placeholder.Controls.Add(New TextBox()) 
     ticketNum_Placeholder.Controls.Add(New TextBox()) 

    Next 

    IterateThroughBooking(Me) 
    IterateThroughReservation(Me) 
    IterateThroughTitle(Me) 
    IterateThroughFirstname(Me) 
    IterateThroughSurname(Me) 
    IterateThroughTicketNum(Me) 

    Retreive_first_row() 

End Sub 

Protected Sub testconn_submit_Btn_Click(ByVal sender As Object, ByVal e As EventArgs) Handles testconn_submit_Btn.Click 

    Filldata() 

End Sub 

Protected Sub next_submit_Btn_Click(ByVal sender As Object, ByVal e As EventArgs) Handles next_submit_Btn.Click 

    validate() 

    If valid = "fail" Then 

    Else 

     Step1_Pnl.Visible = False 
     Step2_Pnl.Visible = True 
     CreateTextBoxes() 
     Button1.Attributes.Add("OnClick", "validate_step2(); return false;") 
    End If 

End Sub 

Protected Sub clear_submit_Btn_Click(ByVal sender As Object, ByVal e As EventArgs) Handles clear_submit_Btn.Click 

    title_Txt.Text = "" 
    first_name_Txt.Text = "" 
    surname_Txt.Text = "" 
    company_name_Txt.Text = "" 
    contact_number_Txt.Text = "" 
    contact_email_Txt.Text = "" 
    number_of_tickets_Ddl.SelectedValue = "Please select" 
    purchase_date_Txt.Text = "" 

    title_error_Lbl.Text = "*" 
    first_name_error_Lbl.Text = "*" 
    surname_error_Lbl.Text = "*" 
    comnpany_name_error_Lbl.Text = "*" 
    contact_phone_error_Lbl.Text = "*" 
    contact_email_error_Lbl.Text = "*" 
    number_of_tickets_error_Lbl.Text = "*" 
    date_of_purchase_error_Lbl.Text = "*" 

End Sub 

Protected Sub back_Btn_Click(ByVal sender As Object, ByVal e As EventArgs) Handles back_Btn.Click 

    Step1_Pnl.Visible = True 
    Step2_Pnl.Visible = False 

End Sub 

Protected Sub next_submit2_Btn_Click(ByVal sender As Object, ByVal e As EventArgs) Handles next_submit2_Btn.Click 

    validate_step2() 

End Sub 

End Class 
+0

您可以使用现有的隐藏控件来告诉您需要创建多少个动态控件。您也可以考虑更改用户界面,以便您不必以此方式创建动态控件。 – Oded 2012-08-17 10:54:14

+0

我原本有一个非常简单的10行控件网格,其中只有可见性发生了变化。这看起来非常麻烦,我认为“动态”只能是更好。 – Ryan 2012-08-17 11:15:00

回答

0

第一次您的用户选择在下拉菜单中的项目下来,你得到的数量和创建动态控件。诀窍在于记住下一个PostBack的计数。

您可以使用会话来记住这个计数。

现在,当您收到第二个PostBack时,您可以重新创建Init上的控件。如果您希望这些动态创建的控件接收事件,Load为时已晚。

+0

这是否会有效地“销毁”控件,然后根据最初创建它们的数量重新创建新控件?如果这样做是有道理的,但我怎么也保留控件的价值? – Ryan 2012-08-17 11:22:18

+0

Http是无状态的。控件始终在每个请求上创建。当它加载'ViewState'时,Asp.net填充值。如果您生成的第一次使用相同的ID,则asp.net将完成剩余的ID。 – nunespascal 2012-08-17 11:24:20

+0

@Ryan - ViewState在Page_Init之后和Page_Load之前应用。您必须像以前一样创建完全相同的控件,否则您将收到“ViewState无法应用”错误。 – 2012-08-17 11:26:25

1

通常,创建动态控件时,人们可能会在Page_Init创建控件并设置事件处理程序和所有的初始属性(即ID,姓名,风格,文本等)。发生回发时,ViewState将在Page_Init之后应用(前提是启用了ViewState)。

在这种情况下,我将更改为中继器或某种数据网格控件,并使用数据绑定来填充它。中继器控件可以将数据绑定到基本数字数组中,重复您的模板X次。与中继器这样的

很好的例子可以在这里找到:VB.NET Repeater Simple Data Binding Without Datasource

+0

看来我还是不太'相信'。如果我在Page_Init中生成控件的代码基本上说 - 创建一个从1到DDL中的任何一个循环,然后创建许多行控件,这将在DDL被选中之前发生,它将如何“知道'要创建多少行? – Ryan 2012-08-17 11:09:00

+0

我看到你的问题...切换到中继器控制 – 2012-08-17 11:20:04

+0

我根本没有中继器的经验,你是否能够阐明他们和他们的使用? – Ryan 2012-08-17 11:29:44

相关问题