2009-03-27 6 views
0

Voici le problème .... J'ai trois composants ... Une page qui contient un contrôle utilisateur et un contrôle côté serveur qui est dans le contrôle de l'utilisateur. Le contrôle utilisateur a une poignée d'événements que la page écoute pour modifier ce que fait le contrôle côté serveur.Événements de contrôle .NET et cycle de vie de la page

Le contrôle serveur crée essentiellement une liste de recherche TV-Guide remplie de nombreuses commandes ASP.NET plus petites qui doivent avoir des événements. Tous ces contrôles sont créés dynamiquement (côté serveur évidemment). Le remplissage de ce contrôle côté serveur nécessite des opérations qui sont de nature intensive et ne doivent donc être effectuées qu'une seule fois par publication. Event1 et Event2 fire et vont fondamentalement changer les choses sur le rendu des contrôles côté serveur (tri, filtrage, etc) alors quand ils tirent, j'ai besoin d'appeler PopulateControls à coup sûr.

Voici le problème: je ne trouve pas le meilleur endroit pour mettre l'appel à PopulateControls. Si je le mets dans le PageLoad, il se déclenche et dessine la liste avant tous les événements. Ensuite, mes événements doivent appeler eux-mêmes PopulateControls pour répondre à l'événement. Si je mets l'appel dans PreRender, les événements du contrôle côté serveur ne se déclenchent pas car d'après ce que j'ai lu, ils doivent être créés avant ou pendant PageLoad.

Alors, où dois-je mettre cet appel de sorte que je n'ai qu'à l'appeler une fois et pour qu'il puisse répondre aux événements appropriés?

Voici quelques pseudo-code

public class MyPage : System.Web.UI.Page 
{ 
    protected UserControl MyUserControl; 

    // Wire up event handlers 
    MyUserControl.Event1 += OnEvent1; 
    MyUserControl.Event2 += OnEvent2; 

    public Page_Load() 
    { 
    } 

    public PreRender() 
    { 
     PopulateControls(); 
    } 

    private PopulateControls() 
    { 
     // Do intensive operation to populate controls 
    } 

    protected OnEvent1() 
    { 
    } 

    protected OnEvent2() 
    { 
    } 
} 

Répondre

1

je pourrais manquer quelque chose ici, mais je vais prendre une fissure à cela de toute façon. Vous devez créer la hiérarchie de contrôle de la même manière que sur le rendu inital pour que vos identifiants correspondent et permettent à vos événements de se déclencher correctement. Il semble que vous ayez besoin de réorganiser après un événement, vous devrez donc créer les contrôles deux fois.

Editer: Vous devez être en mesure de recréer vos contrôles et la hiérarchie de contrôle à posteriori. Vous devriez envoyer suffisamment d'informations au client pour que vous puissiez recréer les contrôles correctement sur Postback. Cela peut être fait en sauvegardant des informations dans ViewState si nécessaire.

Vous ne devez recalculer les informations de contrôle que lorsque cela est nécessaire. Dans votre cas à cause d'un événement post retour.

Le flux de base devrait être comme ceci. Dans votre événement Load, si vous n'avez pas l'ViewState nécessaire pour créer vos contrôles, appelez votre méthode populate, sinon créez-les à partir de ViewState. Lorsqu'un post-retour se produit, l'événement Load va les créer, mais ils sont en cours de reconstruction à partir de viewstate, ce qui devrait être bon marché. Lorsque l'événement postback se déclenche, appelez la méthode populate pour recréer les contrôles dans le nouvel ordre ou avec les nouvelles informations, en fonction de l'événement qui s'est produit.

Chaque fois que je construis un contrôle, j'aime penser à la façon dont le contrôle se comportera si un retour se produit à partir d'un autre contrôle sur la page.Votre contrôle devrait continuer à avoir la même apparence à moins d'être affecté par ce post-retour et il devrait pouvoir être recréé sans aucun accès aux données, mais à partir des informations qu'il a collectées lors d'appels précédents.

J'ai édité ma réponse et j'espère que ceci est un peu plus clair maintenant.

0

contrôles enfants devraient être créés dans CreateChildControls, qui est appelé dans la phase « Init » du cycle de vie de contrôle.

+0

D'accord, mais cela ne résout pas mon problème. Si je les crée là, je vais devoir les RECRÉTER encore quand mon événement se déclenchera plus tard parce que l'événement change ce qui doit être dessiné. – cjserio

0

Le meilleur endroit pour appeler les événements que vous souhaitez appeler avant toute autre chose se produit sur votre page, ou tout contrôle enfant, est à l'étape PageInit.

Voici un article décent qui traite du cycle de vie avec des contrôles utilisateur: http://www.codeasp.net/articles/asp.net/20/aspnet-page-lifecycle

+0

Je n'appelle aucun événement ... Les événements sont en réponse à quelque chose que l'utilisateur a fait ... Par exemple, OnClicks etc. Ils sont touchés après Page_Load juste par la nature de la façon dont .NET fonctionne. – cjserio

+0

Si je comprends bien votre question, vous voulez qu'un événement dans votre commande usercontrol se déclenche avant tout le reste. Cela déclencherait alors des événements dans d'autres endroits, comme dans votre page. Dans ce cas, vous devez mettre votre logique de liaison de contrôle dans le PageInit de votre contrôle, pas la page elle-même. – AaronS

+0

Je suis confus ... Je ne pense pas que l'ordre des événements puisse être ajusté. Voir http://msdn.microsoft.com/en-us/library/ms178472.aspx. Les événements de contrôle se produisent toujours après que le LoadLoad a déjà été exécuté. – cjserio

Questions connexes