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 では、usercontrols のビットを取得し、これらはいくつかの動的コントロールを追加し、それらまたは静的コントロール自体にデータを設定することができます..

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 の静的コントロールは pre_init に間に合うように作成されているように見えないため、それらに値を設定しようとすると失敗します。これに伴い、ユーザー コントロールをリピーターに追加することもできません。これもこの時点ではセットアップされていないためです。

私はこれがライフサイクルの問題であることをよく知っていますが、マスターページに物事を単純にラップするだけですべてのイベントが完全に台無しになる可能性があることを理解していません。 UC は pre_init に戻るため、ビューステートを使用してそれらを取得します..?

誰か教えてください。

ありがとう

ナット

4

1 に答える 1

1

PreInitこの段階では、すべてのコントロールが開始されることが保証されているわけではないためです。実際、ページにマスターがある場合、それらは開始されません。これは、PreInitマスター ページを動的に変更できるホール ライフサイクルの唯一の場所であり、もちろん、マスター ページが設定されていないと ASP.NET エンジンによってコントロールのツリーを完全に構築できないためです。

ここでの最善のアドバイスは、ロジックをPage_InitandPage_Loadハンドラーに移動することです。たとえば、すべてのプロパティの設定と動的コントロールの挿入 (メソッドが行うことだと思います) - 実際、初期化RenderPageControlsを呼び出すことができるものはすべてに配置する必要があります。データのロード (おそらく の呼び出し) は 内で行う必要があります。ページ ライフ サイクルのどの段階で推奨されるアクションの詳細については、こちらを参照してください。Page_InitLoadPaxDataPage_Load

ただし、すべてのコードをどうしても実行したい場合(スニペットPage_PreInitでその理由はわかりませんが) - 回避策があります。ハンドラの先頭に次の行を挿入します。

MasterPage master = this.Master; 

これにより、例外が消えます。このトリックが機能する理由は、Masterプロパティの呼び出しが、すべてのasp:Contentコントロールのコンテンツの生成を含むマスター ページの作成をトリガーするためです。それでも、これは一般的な情報のためのものであり、推奨される方法ではありません。

于 2012-08-10T08:57:32.717 に答える