0

我有一个(以前)工作正常的 aspx 页面

它由 aspx 中的一些简单控件组成-它们需要动态设置它们的值 aspx 中的一些用户控件需要将一些数据传递给它们一些通过中继器动态添加的用户控件..以及用户控件中的一些控件需要动态创建

它被设置为在 pre_init 事件中完成大部分工作 - 这样我就可以在页面和用户控件中创建动态控件,以便它们保持其视图状态。

因此:

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
    paxID = Integer.Parse(Request.QueryString("g"))
    pax = New Pax(paxID)

    If Not IsPostBack Then
        ddlTitle.SelectedValue = pax.Title
        txtFirstname.Text = pax.FirstName
        txtSurname.Text = pax.Surname
        ddlGender.SelectedValue = pax.Gender.ToUpper()
        If (pax.DOB IsNot Nothing) Then
            txtDOB.Text = CType(pax.DOB, DateTime).ToString("dd/MM/yyyy")
        End If

        txtNationality.Text = pax.Nationality
        txtPassportNumber.Text = pax.PassportNumber

        If pax.Discount IsNot Nothing Then
            txtDiscount.Text = Math.Abs(pax.Discount.Price).ToString()
        End If
    End If
    LoadPaxData()
    RenderPageControls()

End Sub

Protected Sub RenderPageControls()

    ''work out how many weeks we are dealing with
    Dim weeks = Math.Floor(bk.nights / 7)
    If bk.nights Mod 7 <> 0 Then
        weeks += 1
    End If

    ''grab ALL the AVAILABILITY options for ALL weeks
    For ii = 1 To weeks
        Dim dt = DateAdd(DateInterval.Day, (ii - 1) * 7, theDate)
        allMHOptions.AddRange(AvailabilityOptionFactory.GetMainHolidayOptionAvailability(dt))
        allTravelOptions.AddRange(AvailabilityOptionFactory.GetTravelOptionAvailability(dt))
        allOptions.AddRange(AvailabilityOptionFactory.GetOptionAvailability(dt))
    Next

    allExtras = AvailabilityOptionFactory.GetExtrasAvailability(theDate)

    ''now all the booked options
    allBooked = Booked.BookedOptionFactory.LoadBookedOptions(pax.id)

    Dim tabContent = New Dictionary(Of String, Integer)
    ''WEEK tabs
    For i = 1 To weeks
        tabContent.Add(String.Format(divIdFormat, i.ToString()), i)
    Next

    ''bind the repeaters with the week data
    rptULTabs.DataSource = tabContent
    rptULTabs.DataBind()
    rptTabs.DataSource = tabContent
    rptTabs.DataBind()

    ''EXTRAS tab
    ucExtras.extraOptions = allExtras
    ucExtras.alreadyBooked = allBooked

    ''SUPPLEMENTS tab
    ucSupplements.p = pax

    ''TRAVEL tab
    ucTravel.travelOptions = allTravelOptions
    ucTravel.alreadyBooked = Booked.BookedOptionFactory.LoadTravelOptions(pax.RecNum, Nothing)
    ucTravel.outboundWeekStart = theDate
    ucTravel.returnWeekStart = DateAdd(DateInterval.Day, (weeks - 1) * 7, theDate)
        ucTravel.returnDate = depDate
End Sub

loadpaxdetails 将一些额外的细节加载到 pax 对象上

在 RenderPageControls 中,它获取用户控件的位,而这些位又可以添加一些动态控件并在这些控件或任何静态控件上设置任何数据。

..

<div id="divTabs" runat="server">
    <ul id="ulTabs">
        <asp:Repeater runat="server" ID="rptULTabs">
            <ItemTemplate>
                <li><a href="#<%# DataBinder.Eval(Container.DataItem, "Key") %>">Week
                    <%#DataBinder.Eval(Container.DataItem, "Value")%>
                </a></li>
            </ItemTemplate>
        </asp:Repeater>
        <li><a href="#tabExtras">Extras</a></li>
        <li><a href="#tabRequirements">Requirements</a></li>
        <li><a href="#tabTravel">Travel</a></li>
    </ul>
    <asp:Repeater runat="server" ID="rptTabs">
        <ItemTemplate>
            <div id="<%# DataBinder.Eval(Container.DataItem, "Key") %>">
                <uc:WeekTab runat="server" ID="ucWeekTab" EnableViewState="true" />
            </div>
        </ItemTemplate>
    </asp:Repeater>
    <div id="tabExtras">
        <uc:ExtrasTab runat="server" ID="ucExtras" EnableViewState="true" />
    </div>
    <div id="tabRequirements">
        <uc:SupplementsTab runat="server" ID="ucSupplements" EnableViewState="true" />
    </div>
    <div id="tabTravel">
        <uc:TravelTab runat="server" ID="ucTravel" EnableViewState="true" />
    </div>
</div>

现在这一切都很好,直到我决定将aspx放入母版页..

现在发生的事情是,aspx 中的静态控件似乎没有为 pre_init 及时创建,因此在尝试对其设置值时它会崩溃。除此之外,我也无法将用户控件添加到中继器,因为此时也没有设置

我很清楚这是一个生命周期问题,但不明白如何简单地将东西包装在母版页中可以完全搞砸所有事件。我不能简单地将 renderpagecontrols 调用放在页面加载中,因为这不会神奇地设置UC 回到 pre_init 并因此使用视图状态获取它们..?

谁能启发我?

谢谢

纳特

4

1 回答 1

1

PreInit不是控制操作的好地方,因为在这个阶段不能保证所有的控制都会被启动。事实上,当页面有主控时,它们不会被启动。这是因为PreInit在漏洞生命周期中唯一可以动态更改母版页的地方,当然,如果没有设置母版页,ASP.NET 引擎无法完全构建控件树。

这里对您的最佳建议是将您的逻辑移动到Page_Init处理Page_Load程序中。例如,所有属性设置和动态控件插入(我假设这就是方法RenderPageControls所做的)——事实上,所有你可以调用的初始化都应该放在Page_Init. 数据加载(大概是调用LoadPaxData)应该在Page_Load. 可以在此处找到有关在页面生命周期的哪个阶段推荐哪些操作的更多信息。

但是,如果您非常想在其中运行所有代码Page_PreInit(尽管我在代码段中看不到任何原因)-有一种解决方法。在处理程序的开头插入以下行:

MasterPage master = this.Master; 

这将使异常消失。这个技巧起作用的原因是对Master属性的调用触发了母版页的创建,其中包括为所有asp:Content控件生成内容。但仍然 - 这只是一般信息,绝对不是推荐的方式。

于 2012-08-10T08:57:32.717 回答