2008-10-25 5 views
2

J'ai un contrôle de menu (dérivé), qui affiche une assez grande liste d'éléments d'une source de données personnalisée. Je dois désactiver ViewState sur le menu pour éviter le très ennuyeux "Impossible de sélectionner un élément de menu désactivé ou non sélectionnable" quand un autre contrôle provoque la modification de la sélection en cours lors d'une publication.Augmenter OnMenuItemClick sans ViewState?

Malheureusement, lorsque ViewState est désactivé pour le menu, les publications générées par ne déclenchent aucun événement. Si j'active ViewState, l'événement OnMenuItemClick est déclenché. Si je désactive ViewState, OnMenuItemClick n'est pas déclenché. Je suis perplexe.

Je dois quitter ViewState pour le menu, alors comment puis-je gérer les publications à partir du menu actuel? À ce stade, je penche pour l'utilisation de l'événement Load du menu, en analysant __EVENTTARGET pour voir si c'est le Menu, et en partant de là. Cela traiterait techniquement l'événement de publication avant que ce soit normalement, mais je suppose que c'est OK.

De meilleures idées?

Répondre

0

J'ai compris l'essence du problème. En utilisant réflecteur, nous pouvons voir la partie importante (s) de la méthode de bas niveau qui gère la postback réelle et soulève alors l'événement:

string str = HttpUtility.HtmlDecode(eventArgument); 
... 
MenuItem item = this.Items.FindItem(str.Split(new char[] { '\\' }), 0); 
if (item != null) 
    this.OnMenuItemClick(new MenuEventArgs(item)); 

Comme vous pouvez le voir les MenuEventArgs est remis un MenuItem. Si la collection Items actuelle ne correspond pas aux données postales entrantes, l'événement n'est pas déclenché. Avec ViewState désactivé, le menu n'a pas d'éléments (ils auraient été reconstruits avec ViewState). Donc, l'événement ne sera pas soulevé. Pour contourner ce problème, j'ai dit au menu de se construire pendant Load en utilisant les données non encore mises à jour (à ce stade, il sera le même qu'à la fin de la dernière requête). C'est essentiellement la même chose que la reconstruction du menu de ViewState, donc je ne me sens pas mal en ce qui concerne la performance, ou peu importe. OnMenuItemClick est ensuite déclenché comme prévu. Enfin, lors de PreRender, je dis au menu de recréer une fois de plus, afin qu'il reflète les changements qui sont survenus pendant la partie du cycle de vie de traitement de publication.

J'ai perdu beaucoup de temps à ce sujet, donc j'espère que cette information peut aider quelqu'un d'autre dans une situation similaire.

1

Oui, vous pouvez choisir, soit utiliser viewstate pour repeupler un contrôle lié ou vous pouvez le numériser avant que les événements soient déclenchés (Page_Load est très bien).

Je ne le lierais pas nécessairement toujours dans Page_PreRender, si rien n'a changé sur cette publication (les changements se sont produits ailleurs sur la page), alors il n'y a aucune raison de le lier à nouveau. Au lieu de cela, vous ne pourrez peut-être lier que sur certains événements lorsque vous saurez qu'il doit changer.

+0

Bonne suggestion, je garderai cela à l'esprit. – sliderhouserules

0

Dans Page_Load, affectez le contrôle à sitemapdata et vérifiez si IsPostBack.

if (IsPostBack) { 
      Menu.DataBind(); 
} 

cela fonctionne pour moi et réduit le viewstate.