2009-10-29 2 views
1

J'ai un contrôle de zone de liste. Lorsque l'utilisateur clique dessus, il indique à un contrôle personnalisé d'utiliser un certain identifiant à utiliser.Résolution des conflits viewstate/namespace

Le contrôle personnalisé dessine la même chose à chaque fois (dynamiquement), il charge juste le contenu différent en fonction de cet ID (il est chargé à partir d'une base de données dans un formulaire dynamique comme le contrôle).

Ok, Maintenant, j'ai des problèmes avec le déversement de viewstate. Lorsque vous cliquez sur la zone de liste pour charger l'ID # 1, tout ira bien. Ensuite, vous cliquez sur ID # 2 et tous les contrôles de zone de texte créés à l'intérieur du contrôle personnalisé ont la même chose qui a été mis dans l'ID # 1. Donc, lorsque l'index de la liste change, je dois effacer l'état de la vue, mais je n'arrive pas à le faire fonctionner.

Tous les contrôles sont créés sur Page_Load également.

J'ai essayé ViewState.Clear() à Page_Load mais cela n'a rien fait.

Le contrôle personnalisé dérive de INamingInterface, mais je suppose que les ID correspondent toujours à viewstate.

J'ai essayé de changer l'ID des contrôles personnalisés pour quelque chose d'unique (comme "CONROL _" + id.ToString()) J'ai aussi essayé de faire la même chose avec le panneau contenant le contrôle personnalisé. Je n'arrive pas à me débarrasser de cet état de vue!

EDIT Ok est le code ici qui illustre le problème

public partial class _Default : System.Web.UI.Page 
{ 
protected void Page_Load(object sender, EventArgs e) 
{ 
    if (ddl.SelectedValue == "1") 
    { 
     Create("ID #1"); 
    } 
    else if (ddl.SelectedValue == "2") 
    { 
     Create("ID #2"); 
    } 
} 
void Create(string text) 
{ 
    TextBox t = new TextBox(); 
    t.Text = text; 
    pnl.Controls.Add(t); 
} 
} 

le balisage:

<div> 
    <asp:Panel ID="pnl" runat="server"> 
     <asp:DropDownList ID="ddl" runat="server" AutoPostBack="True"> 
     <asp:ListItem Text="id 1" Value="1"> 
     </asp:ListItem> 
     <asp:ListItem Text="id 2" Value="2"></asp:ListItem> 
     </asp:DropDownList> 
    </asp:Panel> 
</div> 

Si vous exécutez ce code, vous remarquerez que si vous changez ce qui est dans la zone de texte et alors vous changez la liste déroulante, alors ce que vous avez tapé plus tôt sera gardé là au lieu d'être écrasé ..

Mon objectif de base avec ceci est de faites en sorte que lorsque vous changez d'ID # 2, il place "ID # 2" dans la zone de texte quoi que ce soit (de préférence sans désactiver viewstate)

+0

Pourriez-vous ajouter du code pour nous illustrer vos problèmes? –

+0

Cela vous aide-t-il? – Earlz

Répondre

1

Si je mets l'ID du contrôle de texte alors il ne le fait pas conserver l'ancienne valeur. Donnez-vous à tous les contrôles un identifiant unique?

void Create(string text) 
{ 
    TextBox t = new TextBox(); 
    t.ID = text; 
    t.Text = text; 
    pnl.Controls.Add(t); 
} 
+0

Pas tous les contrôles car 50-75 sont créés dynamiquement. Y a-t-il un moyen de l'obtenir afin que je puisse juste l'emballer dans un INamingContainer et juste lui donner un ID unique parce que faire un refactoring énorme juste pour donner des ID inutiles aux champs génériques me semble faux – Earlz

+0

Les contrôles personnalisés devraient implémenter le INamingContainer interface, puis tous les contrôles que vous créez dynamiquement et que vous souhaitez mettre à jour correctement doivent avoir un ID unqiue dans le contorl personnalisé. –

+0

Aussi douloureux soit-il, cela résout aussi complètement les problèmes de post-retour (comment les contrôles sont restaurés aux valeurs de publication après OnLoad) ... Alors maintenant, allez simplement ajouter des identifiants à environ 40 ou 50 contrôles dans le code ... – Earlz

0

Vous ne pouvez pas faire comme ça.

Pour que viewstate fonctionne correctement, toutes les commandes doivent être créées avant d'être chargées et avec le même identifiant. Vous devez donc stocker les définitions de contrôle dans la session et les recréer avec les mêmes ID pour ASP.NET charger leurs propriétés à partir de l'état d'affichage. Page_load est trop tard, faites-le au PreLoad.

Mais il est plus facile d'avoir tous les contrôles créés au moment du design avec le paramètre visible à false, et d'alterner leur visibilité afin que viewstate fonctionne correctement.

+0

Nous ne pouvons pas faire tout le contrôle étant chose invisible parce que cela nécessiterait de charger des milliers de contrôles dynamiques hors de la base de données à la fois (quand c'est vraiment seulement 30-50 contrôles en même temps sur une page). Et nous ne pouvons pas le changer pour utiliser PreLoad 1. Parce qu'il est dans un webpart, cet événement n'est pas disponible, et 2. Nous ne pouvons pas l'avoir dans Page_Init parce que viewstate n'est pas disponible pour la liste déroulante. – Earlz

+0

Je pense que c'est mieux pour vous de créer un contrôle serveur, là vous aurez toute liberté pour définir ce qui sera sauvegardé dans viewstate. – Wagner

0

En fait, ce n'est plus pertinent. Nous l'avons corrigé en désactivant simplement viewstate pour nos contrôles créés dynamiquement. Cela ne fonctionnerait pas dans tous les cas, mais dans notre cas, il y a deux boutons que l'utilisateur peut pousser (qui concernent les contrôles dynamiques) ou une zone de liste pour changer de forme. Les deux boutons enregistrent l'état des contrôles dans la base de données, donc viewstate n'est pas vraiment nécessaire (je suis toujours confus quand je pense à viewstate et comment il interagit avec les contrôles.Donc, un conseil de base: Si vous avez du mal à contrôler le viewstate, assurez-vous que vous en avez réellement besoin.

+0

Attendez, en fait cela ne fonctionne pas désactiver viewstate .. donc ce n'est pas un problème viewstate ... * votes pour la fermeture * – Earlz

Questions connexes