代码之家  ›  专栏  ›  技术社区  ›  nat

主页面破坏pre_init

  •  0
  • nat  · 技术社区  · 12 年前

    我有一个aspx页面,运行良好

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

    它是在preinit事件中完成大部分工作的,这样我就可以在页面和用户控件中创建动态控件,以便它们保持自己的视图状态。

    因此:

    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中,它获取用户控件的位,而用户控件又可以添加一些动态控件,并在这些控件或任何静态控件上设置任何数据。。

    aspx。。

    <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中的静态控件似乎没有及时为preinit创建,因此在尝试对其设置值时会失败。 除此之外,我也无法将用户控件添加到中继器中,因为目前还没有设置

    我很清楚这是一个生命周期的问题,但我不明白简单地将东西包装在母版页中会如何完全破坏所有事件。。 我不能简单地将renderpagecontrols调用放在页面加载中,因为这不会神奇地将UC设置回pre_init,从而使用viewstate获取它们。。?

    有人能启发我吗?

    谢谢

    天然气

    1 回复  |  直到 12 年前
        1
  •  1
  •   Andrei    12 年前

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

    这里对你最好的建议是把你的逻辑转移到 Page_Init Page_Load 处理程序。例如,设置所有属性并插入动态控件(我认为这是什么方法 RenderPageControls 是的)-事实上你所能调用的 初始化 应该放在 页面_信息 .数据加载(可能调用 LoadPaxData )应该在 页面加载(_L) 。可以找到有关在页面生命周期的哪个阶段建议执行哪些操作的更多信息 here

    但是,如果 非常 希望在中运行所有代码 Page_PreInit (尽管我在片段中看不出有什么原因)-有一个变通方法。在处理程序的开头插入以下行:

    MasterPage master = this.Master; 
    

    这将使例外情况消失。这个技巧之所以有效,是因为 Master 属性触发母版页的创建,其中包括为所有用户生成内容 asp:Content 控制。但是,这只是一般信息,绝对不是推荐的方式。