2010-11-15 4 views
0

C'est probablement quelque chose de fondamental et de stupide que j'ai manqué, mais les différentes solutions de contournement me causent d'énormes maux de tête qui, vraiment, je dois comprendre le problème de base ici pour trouver le meilleure solution.Dropdown in .net usercontrol ne pas maintenir l'état

J'ai un usercontrol qui contient une liste déroulante.

<asp:DropDownList ID="ddlOrderStatus" AutoPostBack="true" runat="server" CssClass="textbox"> 
    <asp:ListItem value="8">Pending</asp:ListItem> 
    <asp:ListItem value="9">On Hold</asp:ListItem> 
    <asp:ListItem Value="11">Complete</asp:ListItem> 
    <asp:ListItem Value="12">Cancelled</asp:ListItem>    
</asp:DropDownList> 

Il ne fait rien dans son événement Page_Load.

Ceci est à son tour contenu dans une page qui, dans son événement Page_Load, effectue une liaison de données sur certains contrôles de répéteurs sur la page mais ne touche pas le contrôle contenant le ddl. Il n'y a pas d'ajax sur la page.

La liste déroulante est clairement définie sur autopostback = true. Le code postback ressemble à ceci:

Private Sub ddlOrderStatus_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ddlOrderStatus.SelectedIndexChanged 
    Dim ddl As DropDownList = DirectCast(sender, DropDownList) 
    Dim currentsorting As String = Request.QueryString("sort") 
    Dim currentpaging As String = Request.QueryString("page") 
    Response.Redirect(String.Format("~/admin/orders/Manage/0?sort={0}&page={1}&status={2}", currentsorting, currentpaging, ddl.SelectedValue)) 
End Sub 

Ainsi, lorsque le ddl est changé, la page ne fait un double postback. Je ne vois aucun moyen d'éviter cela car j'ai besoin de faire une publication pour obtenir la valeur dans le ddl puis une autre publication pour obtenir de nouvelles données du serveur en fonction de cette valeur. Quoi qu'il en soit, le plus long et le plus court est que lorsque vous faites cela, la liste déroulante ne parvient pas à maintenir son état. Donc, vous sélectionnez une valeur, le code fait le travail auquel il est censé - obtient la valeur sélectionnée, puis affiche de nouveau le nouveau jeu de données attendu - puis, lors du chargement, la liste déroulante est de nouveau dans sa forme par défaut. C'est un problème pernicieux pour moi à cause de ce double postback: si j'essaie de définir la valeur du ddl pour égaler ce qui est dans la chaîne de requête, je l'ai, effecitately, mis à cette valeur de façon permanente parce que Page_Load - où le value is set - se produit avant que les événements ne soient traités et que la valeur reste inchangée. J'ai essayé de déplacer le code qui a changé la valeur sélectionnée de ddl en Render, mais il semblait que bien que la valeur sélectionnée ait changé aussi loin que l'utilisateur pouvait voir, la valeur sélectionnée était toujours la valeur par défaut pendant le traitement et traitée comme telle.

J'ai également essayé de définir la valeur selectedValue en session, puis de l'effacer dès qu'elle était remplie. Cela a fonctionné pour certains scénarios, mais malheureusement, cette page contient également du javascript qui peut provoquer sa publication - et vous ne pouvez pas définir de session à partir du javascript côté client. Donc cette idée a dû sortir par la fenêtre.

Je suis à perte ici - ce problème apparemment simple a mangé une journée entière de mon temps. Quelqu'un peut-il soit me dire pourquoi l'état n'est pas maintenu sur ce contrôle et/ou suggérer une façon de montrer la bonne valeur après la publication sans transformer la sélection en une permanente?

Cheers, Matt

+0

N'essayant pas d'être un smartass, mais je recommande de lire sur le framework ASP.NET. [Début ASP.NET 3.5 en VB 2008: De Novice à Professionnel, Deuxième édition] (http://www.amazon.com/gp/product/159059892X?ie=UTF8&tag=aspnettelligent-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=159059892X) –

Répondre

2

Dans votre page charge:

// Only set the selected order status when the page first loads, but not on postbacks. 
if(!Page.IsPostback) 
{ 
    ddlOrderStatus.SelectedValue = Request.QueryString("status"); 
} 

Note:

Je ne vois aucune façon d'éviter ce que je dois faire un postback pour obtenir le valeur dans le ddl puis une autre publication à obtenir de nouvelles données à partir du serveur basé sur ce valeur.

Vous pouvez le faire de javascript

+0

Merci. Je ne peux pas croire en rétrospective que j'étais assez stupide pour manquer ça. Mais j'avais seulement eu environ 3 heures de sommeil. –

+0

La privation de sommeil est l'une des choses les plus horribles. Se reposer! – Greg

1

Je vais commencer par dire que je fais ma programmation ASP.NET en C# et utiliser GridViews, mais ce qui suit devrait appliquer à votre situation indépendamment:

Est-il nécessaire que vous utilisiez la chaîne de requête pour stocker ces données? Si vous avez déclaré vos contrôles de pagination et de tri sur votre page ASPX, vous pouvez y accéder et leurs valeurs directement dans votre codebehind (comme Greg l'a démontré dans le code ci-dessus en n'effectuant pas d'appel FindControl). Est-ce que la configuration du contrôle de l'utilisateur vous a empêché de pouvoir le faire? Instanciez-vous le contrôle utilisateur contenant cette liste déroulante sur une page, puis essayez d'accéder à la valeur de la liste déroulante à partir du code de la page derrière lui, plutôt que du code du contrôle utilisateur derrière?

+0

Juste pour que vous sachiez que la raison est parce que j'ai dû utiliser des contrôles de tri et de pagination personnalisés au lieu des contrôles standard. –

+0

Gotcha. Je n'ai pas eu à gérer le tri et la pagination au-delà du très basique. – jwiscarson