asp:menu e l’evento onmenuitemclick

Erano un paio di giorni che mi arrovellavo per capire perchè l’evento onmenuitemclick del controllo asp.net menu non venisse eseguito.

Come al solito, dopo ore di investigazione, che chissà perchè partono sempre dalle cose più difficili e mai da quelle più ovvie, inizio a trovare la mia risposta.

Va premesso che l’evento viene generato a seguito di un postback sulla pagina stessa; detto questo le cause che evitano lo scatenarsi dell’evento possono essere due:

1) Quando il controllo menu viene renderizzato, i link che vengono generati sono quelli che puntano alla funzione interna javascript __doPostDack. Questa funzione accetta due parametri in ingresso, di cui il secondo è il menu specifico che è stato clicckato.

Se esiste un menu con un identico nome, il framework non sà quale menu clicckare e di conseguenza non scatena l’evento.

Questa prima causa, tuttavia, non era quella a cui appartenevo.

2) Fatto salvo particolari di make-up da parte dell’utente, il link di destinazione generato dal controllo si può vedere nella status bar semplicemente passando il mouse al di sopra del link. E nel mio caso, il link era un link che non faceva il postback. Ecco la causa. Non effettuando il postback verso la pagina di origine, lato server il framwork mai si sarebbe potuto immaginare di scatenare un evento.

Del resto come dargli torto, la navigazione verso un URL specifico, seppur fatta tramite una voce di menu, altro non equivale a l’inserimento del medesimo URL nella barra dell’indirizzo, quindi ad un navigazione diretta, ovvero ad una richiesta ex-nuova a cui nessun evento può essere associato.

Scoperta la causa, non mi restava che capire perchè invece di un link postback, io mi trovavo un link diretto.

Presto detto. Generalmente il controllo asp:menu si utilizza con un SiteMapDataSource, il cui databindings di default, prendendo i dati dal file Web.sitemap (o cmq dal file specificato nel web.config) lavora nel seguente modo:

  1. La proprietà TextField viene associato all’attributo Title del singolo SiteMapNode;
  2. La proprietà NavigationUrl viene associata all’attribu Url del singolo SiteMapNode;

Se si legge nella documentazione MSDN per la proprietà MenuItem.NavigateUrl, nelle note si può leggere quanto segue:

Una voce di menu supporta due modalità: modalità di selezione o modalità di spostamento. Per impostazione predefinita, una voce di menu è in modalità di selezione. Per impostare la modalità di spostamento per una voce di menu, impostare la proprietà NavigateUrl della voce di menu su un valore diverso da una stringa vuota (“”).

Quando una voce di menu è in modalità di spostamento, tutti gli eventi di selezione relativi a tale voce di menu risultano disattivati. Quando viene selezionata una voce di menu in modalità di spostamento, l’utente passa all’URL specificato. Se lo si desidera, è possibile impostare la proprietà Target per specificare la finestra o il frame in cui visualizzare il contenuto collegato.

Ecco allora che tutto appare chiaro, il comportamento del Menu associato al SiteMapDataSource, fa in modo che la modalità del menù venga impostata automaticamente su quella di spostamento.

Se infatti si modifica il comportamento del bindings, evitando l’associazione della proprietà Url, si potrà notare come il menù a questo punto effettui correttamente il PostBack.

Un esempio è possibile vederlo inserendo questa proprietà all’interno del tag



Tuttavia ora sorge un nuovo problema, quello di dover intercettare manualmente la pagina di destinazione, e fare un redirect dopo che l’azione che vi interessa compiere nell’evento MenuItemClick è stata correttamente processata.