Dinamicamente criado DropDownList perde ListItems em Postback
-
05-07-2019 - |
Pergunta
Eu tenho uma página que contém alguns controles criados dinamicamente (TextBox e DropDownList). Quando um postback ocorre, os TextBoxes manter seus valores, mas os DropDownLists perder seus ListItems. Isto é bastante confuso, uma vez que o DropDownList nível de página também mantém seus ListItems. qualquer um pode ver o que há de errado com o código abaixo?
Qualquer ajuda para resolver este problema seria muito apreciada.
<%@ Page Language="VB"%>
<script runat="server">
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
If Not Page.IsPostBack Then
ddlFixed.Items.Add(New ListItem("12", "13"))
ddlFixed.Items.Add(New ListItem("14", "15"))
End If
Dim i As Integer
For i = 0 To 3
Dim ddl As New DropDownList
ddl.ID = "ddlPage" & i
ddl.EnableViewState = True
If Not Page.IsPostBack Then
ddl.Items.Add(New ListItem("12", "13"))
ddl.Items.Add(New ListItem("14", "15"))
End If
pnlDynamic.Controls.Add(ddl)
Dim txtBx As New TextBox
txtBx.ID = "txtPage" & i
If Not Page.IsPostBack Then
txtBx.Text = "Preset"
End If
pnlDynamic.Controls.Add(txtBx)
Next
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server" enableviewstate="true">
<div>
<br />
<br />
<a href="Default.aspx">Get-Request</a>
<br />
<br />
<asp:Panel runat="server" ID="pnlDynamic" EnableViewState="true" />
<br />
<br />
<asp:DropDownList runat="server" ID="ddlFixed" />
<asp:Button runat="server" ID="btn" Text="Postback"/>
</div>
</form>
</body>
</html>
Solução
Eu encontrei a solução que me permite manter o estado de visualização em postagens. É para chamar TrackViewState do ItemCollection.
CType(ddl.Items, IStateManager).TrackViewState()
Obrigado a todos por sua ajuda.
Esta é a solução de trabalho:
<%@ Page Language="VB"%>
<script runat="server">
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
If Not Page.IsPostBack Then
ddlFixed.Items.Add(New ListItem("12", "13"))
ddlFixed.Items.Add(New ListItem("14", "15"))
End If
Dim i As Integer
For i = 0 To 3
Dim ddl As New DropDownList
ddl.ID = "ddlPage" & i
CType(ddl.Items, IStateManager).TrackViewState()
If Not Page.IsPostBack Then
ddl.Items.Add(New ListItem("12", "13"))
ddl.Items.Add(New ListItem("14", "15"))
End If
pnlDynamic.Controls.Add(ddl)
Dim txtBx As New TextBox
txtBx.ID = "txtPage" & i
If Not Page.IsPostBack Then
txtBx.Text = "Preset"
End If
pnlDynamic.Controls.Add(txtBx)
Next
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server" >
<div>
<br />
<br />
<a href="Default.aspx">Get-Request</a>
<br />
<br />
<asp:Panel runat="server" ID="pnlDynamic" />
<br />
<br />
<asp:DropDownList runat="server" ID="ddlFixed" />
<asp:Button runat="server" ID="btn" Text="Postback"/>
</div>
</form>
</body>
</html>
Outras dicas
A DDL manterá seus itens e seleção quando viewstate é habilitado. A caixa de texto irá manter o seu conteúdo, independentemente do estado de visualização desde a volta resultando html é escrito para o servidor em uma nova postagem.
Acho courious que você tem todas essas declarações viewstate em seu código e marcação.
Uma das várias coisas está acontecendo:
- ViewState para o controle está desativado
- ViewState acima da hierarquia contrl está desativado (página, um formulário painel)
- Você está dinamicamente adicionar o controle demasiado tarde no ciclo de página para a seleção a ser carregada a partir de viewstate. Carregando no INIT deve ser fino.
Pode ser que você precisa ativar explicitamente o ViewState para aqueles DropDownLists ...
EDIT: Isto é o que quero dizer com o meu último comentário ...
<script runat="server">
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
If Not Page.IsPostBack Then
ddlFixed.Items.Add(New ListItem("12", "13"))
ddlFixed.Items.Add(New ListItem("14", "15"))
Dim i As Integer
For i = 0 To 3
Dim ddl As New DropDownList
ddl.ID = "ddlPage" & i
ddl.EnableViewState = True
ddl.Items.Add(New ListItem("12", "13"))
ddl.Items.Add(New ListItem("14", "15"))
pnlDynamic.Controls.Add(ddl)
Dim txtBx As New TextBox
txtBx.ID = "txtPage" & i
txtBx.Text = "Preset"
pnlDynamic.Controls.Add(txtBx)
Next
End If
End Sub
</script>
Eu sempre uso Page_Load
e nunca ter problemas como este. Talvez algo que você poderia olhar.
Eu geralmente dados ligam a controles a primeira vez que a página é carregada, e depois disso vamos VIEWSTATE punho postagens etc. Note-se que eles sugerem que ligares dados durante Page_Load
...
Confira http://support.microsoft.com/kb/305141
página Eventos loadTOCNode (2, 'moreinformation'); Durante o ciclo de vida de uma página ASP.NET, alguns eventos padrão que estão expostas a partir do página objeto são usados ??com freqüência. A estrutura página ASP.NET conecta-se automaticamente (ou fios para cima) delegado instâncias adequadas a prazo tempo para estes métodos. Isso evita que você tenha de escrever a cola necessária" código." A lista a seguir apresenta o delegado instâncias que estão ligados cima tempo de execução na ordem em que são disparados:A lista a seguir descreve os eventos que são não-determinístico:
- Page_Init : Durante este evento, você pode inicializar valores ou conectar qualquer manipuladores de eventos que você pode ter
- Page_Load :. Durante este evento, você pode executar uma série de ações para tanto criar sua página ASP.NET pela primeira vez ou responder a eventos do lado do cliente que resultam de um post. O estado da página e visualização de controle foram restaurados antes deste evento. Use a propriedade IsPostBack página para verificar se esta é a primeira vez que o página está sendo processado. Se é a primeira vez, efectuar a ligação de dados. Além disso, ler e propriedades de controle de atualização
- Page_DataBind :. O DataBind evento é gerado quando o DataBind método é chamado na página nível. Se você chamar DataBind em controles individuais, ele só dispara o DataBind caso dos controles abaixo dela
- Page_PreRender .: o PreRender evento é acionado imediatamente antes de o estado de exibição é salvo eo controles são prestados. Você pode usar esse evento para executar qualquer último minuto operações em seus controles
- Page_Unload :. Depois de uma página tem renderização acabado, o incêndios Page_Unload de eventos. Este evento é um bom lugar para executar a limpeza final, trabalhos. Isto inclui itens tais como a limpeza da base de dados de ligações abertas, descartando objetos, ou fechar os arquivos que estão abertos.
- Page_Error : Se ocorrer uma exceção não tratada durante o processamento da página, o Erro incêndios de eventos. O Erro evento dá-lhe uma oportunidade de alça graciosamente erros
- Page_AbortTransaction :. Transaction eventos são úteis se você quiser indicar se uma transação bem ou mal sucedida. Este evento é comumente usado para Carrinho cenários em que este evento pode indicar o sucesso ou fracasso de uma ordem. Este evento é acionado quando uma transação foi abortada
- Page_CommitTransaction :. Este evento é acionado quando uma transação foi confirmada com sucesso.
Os itens de lista em um DropDownList não são armazenadas no estado de exibição. Você vai ter que adicioná-las a cada nova postagem.
O que está armazenada no estado da exibição é o índice escolhido - ie. o 'valor' do controle.
Editar: Bem, parece que eu aprendi alguma coisa hoje. Eu corrijo: -)