Внимание!Эта проблема не для финт сердца.Я потратил несколько дней, пытаясь устранить его.
У меня есть Wizard
элемент управления с примерно 5 шагами, каждый из которых имеет несколько элементов управления, от очень простых до очень сложных, таких как пользовательская комбинация jQueryкоробки на основе DropDownList
с и TextBox
с.Каждый шаг имеет несколько элементов управления, заключенных в элемент управления PlaceHolder
.
Wizard
вместе со всеми PlaceHolder
s и их дочерним элементом Controls
вложены в View
из MultiView
.На той же странице у меня есть еще один View
в стиле формы, но не один.Это представление имеет соответствующие PlaceHolder
с для каждого из PlaceHolder
с на каждом шаге Wizard
.
. В зависимости от ReferralUrl, я вызываю следующую функцию, чтобы «переключить» представление из Wizard
в представление стиля формы, переместив все элементы управления, а затем установив активное представление следующим образом:
Protected Sub ToggleView() Handles ViewToggle.Click
If Wizard_mv.ActiveViewIndex = 0 Then
ViewToggle.Text = "Toggle Wizard View"
fPH1.Controls.Add(wPH1)
fPH2.Controls.Add(wPH2)
fPH3.Controls.Add(wPH3)
fPH4.Controls.Add(wPH4)
fPH5.Controls.Add(wPH5)
Wizard_mv.ActiveViewIndex = 1
ElseIf Wizard_mv.ActiveViewIndex = 1 Then
ViewToggle.Text = "Toggle Form View"
wPH1.Controls.Add(fPH1)
wPH2.Controls.Add(fPH2)
wPH3.Controls.Add(fPH3)
wPH4.Controls.Add(fPH4)
wPH5.Controls.Add(fPH5)
Wizard_mv.ActiveViewIndex = 0
End If
End Sub
Сразу после этого я использую другую функцию для предварительного заполнения элементов управления значениями из записи в базе данных.,После разрешения пользователям вносить некоторые изменения, они могут повторно отправить обновленную запись в базу данных.Проблема в том, что это прекрасно работает, если я делаю это с Wizard
, но не после переключения.Трассировка показывает, что Control Tree
пуст во время отправки обновленной записи, и, следовательно, я не могу получить введенные пользователем / предварительно заполненные значения из этого представления. Предварительная заливка отлично работает, и все "выбранные" значения верны.Проблема возникает в PostBack после нажатия кнопки отправить, и он теряет все значения и элементы управления.
Пожалуйста, не отвечайте, если вы полностью не понимаете мою проблему и не готовы помочь.Я думаю, что проблема очень хорошо лежит в жизненном цикле страницы.При отправке из моего мастера при обратной передаче в Page_Init загадочным образом я загружаю свои контрольные значения, однако при отправке из представления формы не загружаются ни элементы управления, ни их значения.Из того, что я прочитал, это вопрос постоянства.Очень надеюсь, что для этого есть относительно простое решение.
Вот пример моей разметки в моем Wizard
(все стили для краткости удалены):
<asp:WizardStep ID="WizardStep1" runat="server" Title="Product Info">
<asp:PlaceHolder ID="wPH1" runat="server" ViewStateMode="Enabled">
<asp:Table ID="ProductInfoTable" runat="server" Width="100%">
<asp:TableHeaderRow>
<asp:TableHeaderCell><h3>Product Line</h3></asp:TableHeaderCell>
<asp:TableHeaderCell><h3>Publication Type</h3></asp:TableHeaderCell>
<asp:TableHeaderCell><h3>Request Type</h3></asp:TableHeaderCell>
</asp:TableHeaderRow>
<asp:TableRow>
<asp:TableCell>
<div class="ui-widget">
<!-- Autocomplete Combobox -->
<asp:DropDownList ID="productLine_ddl" runat="server" DataSourceID="productLineSDS" ViewStateMode="Enabled" DataTextField="Product" DataValueField="ID"></asp:DropDownList>
<asp:TextBox ID="productLine_cb" runat="server" EnableViewState="True"></asp:TextBox>
<button id="productLine_btn" type="button" title="Show All Items"></button>
</div>
</asp:TableCell>
<asp:TableCell>
<asp:DropDownList ID="docType_ddl" runat="server" DataSourceID="docTypeSDS" DataTextField="DocType" DataValueField="ID"></asp:DropDownList>
</asp:TableCell>
<asp:TableCell>
<asp:DropDownList ID="requestType_ddl" runat="server" DataSourceID="requestTypeSDS" DataTextField="RequestType" DataValueField="ID"></asp:DropDownList>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell ColumnSpan="2">
<asp:MultiView ID="Attachment_mv" runat="server" ActiveViewIndex="0">
<!-- File Upload/Browsing Display -->
<asp:View ID="AttachmentUploadView" runat="server">
<h3 class="inlineH">Attach File: </h3>
<asp:FileUpload ID="AttachmentFile_btn" runat="server" />
<asp:Button ID="UploadFile_btn" runat="server" Text="Upload File" />
</asp:View>
<!-- File Attached Display -->
<asp:View ID="FileAttachedView" runat="server">
<h3 class="inlineH">Uploaded File: </h3>
<asp:Label ID="FileAttachedLabel" runat="server" Text="Label"></asp:Label>
<asp:Literal ID="FilesOnServer" runat="server" />
</asp:View>
</asp:MultiView>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</asp:PlaceHolder>
</asp:WizardStep>
My Page Lifecycle Events, asпросил (в хронологическом порядке для вашего удобства):)
Dim referrerPage As String
'Initialize Dynamic controls here. These are controls that need to be prefilled, etc.
Private Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Init
'DO NOT PREFILL at this stage, as the Controls are not yet rendered and will cause errors.
' Use this section for detecting the "referrerPage" and missing "id" parameters when expected, etc.
If Not IsPostBack Then
ViewState.Clear()
End If
Try
referrerPage = Right(Request.UrlReferrer.AbsolutePath, Len(Request.UrlReferrer.AbsolutePath) - Request.UrlReferrer.AbsolutePath.LastIndexOf("/"c) - 1)
Catch ex As Exception
If Not String.IsNullOrEmpty(Session.Item("referrerPage")) Then
referrerPage = Session.Item("referrerPage")
End If
End Try
If StrComp(referrerPage, "wizard.aspx") <> 0 And String.IsNullOrEmpty(Session.Item("referrerPage")) Then 'Initialize Session state to remember "referrerPage"
Session.Add("referrerPage", referrerPage)
End If
If StrComp(referrerPage, "formdetails.aspx") = 0 Then
If String.IsNullOrEmpty(Request.Params("id")) Then
'This line checks for an expected "id" param value and if none exists, forwards the page back to "tcom.aspx"
Response.Redirect(Request.UrlReferrer.AbsolutePath)
Else
ToggleView()
End If
End If
End Sub
'Prefill Dynamic controls here.
Private Sub Page_PreLoad(sender As Object, e As EventArgs) Handles Me.PreLoad
If Not IsPostBack Then
productLine_ddl.DataBind()
docType_ddl.DataBind()
requestType_ddl.DataBind()
'...and several more DataBinds for each individual
' control in the wizard. Nothing more.
End If
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
If Not IsPostBack Then
'Benign code for querying the database to get User info for Page.User.Identity.Name
End If
End Sub
Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As EventArgs) Handles Me.PreRender
If Not IsPostBack Then
'Here is completely benign code for hiding a couple controls.
End If
End Sub
Protected Sub Page_PreRenderComplete(ByVal sender As Object, ByVal e As EventArgs) Handles Me.PreRenderComplete
'PREFILL HERE when appropriate. This occurs after checking the "referrerPage" and ensuring a value for the "id" parameter.
If Not IsPostBack Then
Try
If Not String.IsNullOrEmpty(Request.Params("id")) Then
PrefillWizard(Request.Params("id"))
Else : output.Text += "Source: " + Request.UrlReferrer.AbsolutePath
End If
Catch ex As Exception
End Try
End If
End Sub
Всем, кто может помочь с этим, вы имеете мою вечную благодарность.;)