1) Definisco la struttura e relative classi per la gestione della configurazione del menù
Imports System.Configuration
Imports System.Xml
Imports System.Xml.Serialization
#Region "MenuItem"
Public Class MenuItem
< XmlAttributeAttribute() > _
Public text As String
< XmlAttributeAttribute()> _
Public navigationUrl As String = String.Empty
< XmlElement("role", IsNullable:=False) > _
Public roles As String()
< XmlElement("menuItem", IsNullable:=False) > _
Public menuItems As MenuItem()
End Class
#End Region
#Region "Menu Configuration Section Handler"
Public Class MenuSectionHandler
Implements IConfigurationSectionHandler
Public Function Create(ByVal parent As Object, ByVal configContext As Object, ByVal section As System.Xml.XmlNode) _
As Object Implements System.Configuration.IConfigurationSectionHandler.Create
Dim ser As New XmlSerializer(GetType(MenuItem), New XmlRootAttribute(section.Name))
Dim r As New XmlNodeReader(section)
Return ser.Deserialize(r)
End Function
End Class
#End Region
2) Aggiungo al progetto un nuovo user control (ascx) al quale aggiungo una Table, controllo server-side, che chiamo "mMenuTable". Nel parte di code behind del controllo implemento quanto segue.
Imports System.Configuration
Imports System.Web.Caching
Public Class Menu
Inherits System.Web.UI.UserControl
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
Private Sub InitializeComponent()
End Sub
Protected WithEvents mMenuTable As System.Web.UI.WebControls.Table
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private ReadOnly Property MenuSchema() As MenuItem
Get
If (Cache.Item("MENU") Is Nothing) Then
Dim vMenuSchema As MenuItem = DirectCast(ConfigurationSettings.GetConfig("menuSection"), MenuItem)
Dim filename As String = MapPath("~/Web.config")
Cache.Insert("MENU", vMenuSchema, New CacheDependency(filename))
Return vMenuSchema
Else
Return DirectCast(Cache.Item("MENU"), MenuItem)
End If
End Get
End Property
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim depth As Integer
AddMenuItem(MenuSchema, depth)
End Sub
Private Sub AddMenuItem(ByVal menuItem As MenuItem, ByRef depth As Integer)
Try
depth = depth + 1
'il flag indicherà se l'utente è in uno dei ruoli associati al menù
Dim userIsInRole As Boolean = True
'controllo se l'utente è in uno dei ruoli associati al menù, se non vi sono ruoli
'associati al menù significa che valgono quelli del menù padre
Dim role As String
If (Not menuItem.roles Is Nothing) Then
For Each role In menuItem.roles
If (Page.User.IsInRole(role)) Then
userIsInRole = True
Exit For
End If
Next
End If
'se l'utente non ha alcun ruolo associato di quelli richiesti
'esco e salto menu e relativa gerarchia
If (Not userIsInRole) Then Exit Sub
'aggiungo menu e ciclo sui sotto menu
AppendMenuItem(menuItem.text, menuItem.navigationUrl, depth)
Dim vMenuItem As MenuItem
If (Not menuItem.menuItems Is Nothing) Then
For Each vMenuItem In menuItem.menuItems
AddMenuItem(vMenuItem, depth)
Next
End If
Finally
depth = depth - 1
End Try
End Sub
Private Sub AppendMenuItem(ByVal text As String, ByVal navigationUrl As String, ByVal depth As Integer)
Dim menuItem As Control
Dim menuText As String = String.Format("{0} {1}", New String("."c, depth - 1), text)
'se viene specifico un navigationurl è un hyperlink else una label
If (navigationUrl = String.Empty) Then
'costruisco label
Dim menuLabel As New Label
menuLabel.Text = menuText
menuItem = menuLabel
Else
'costruisco hyperlink per voce menu
Dim menuLink As New HyperLink
menuLink.Text = menuText
menuLink.NavigateUrl = navigationUrl
menuItem = menuLink
End If
'costruisco cella dove posizionare hyperlink
Dim tdMenuItem As New TableCell
tdMenuItem.Controls.Add(menuItem)
'costruisco riga dove posizionare cella
Dim trMenuItem As New TableRow
trMenuItem.Cells.Add(tdMenuItem)
'aggiungo riga a tabella
mMenuTable.Rows.Add(trMenuItem)
End Sub
End Class
3) Aggiungo le parte di configurazione nel web.config dell'applicazione
< configSections >
< section name="menuSection" type="NorthWindVBNET.MenuSectionHandler, NorthWindVBNET" / >
< / configSections >
< menuSection text="Menu" >
< role >user< / role >
< menuItem text="Home" navigationUrl="~/Home.aspx"/>
< menuItem text="BackOffice">
< role >admin< / role>
< menuItem navigationUrl="~/BackOffice/EmployeesList.aspx" text="Employees List" />
< / menuItem >
< menuItem text="Services">
< menuItem navigationUrl="~/Services/LogOut.aspx" text="Log Out"/ >
< / menuItem >
< / menuSection >
4) Aggiungo/trascino lo user control (che io ho chiamato Menu.ascx) nelle pagine che vogliamo abbiamo il menù.
posted @ lunedì 9 maggio 2005 13:38