代码之家  ›  专栏  ›  技术社区  ›  Christian Hayter

动态更改SiteMapNode的标题

  •  4
  • Christian Hayter  · 技术社区  · 16 年前

    <siteMap defaultProvider="default" enabled="true">
      <providers>
        <add siteMapFile="~/Web.sitemap" securityTrimmingEnabled="true" name="default" type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      </providers>
    </siteMap>
    

    Title

    SiteMapResolve 活动。这似乎并不重要 此事件已处理,我已在中显示 Global.asax

    Public Class Global_asax
        Inherits System.Web.HttpApplication
    
        Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
            AddHandler SiteMap.SiteMapResolve, AddressOf SiteMapResolve
        End Sub
    
        Sub Application_EndRequest(ByVal sender As Object, ByVal e As EventArgs)
            RemoveHandler SiteMap.SiteMapResolve, AddressOf SiteMapResolve
        End Sub
    
        Private Shared Function SiteMapResolve(ByVal sender As Object, ByVal e As SiteMapResolveEventArgs) As SiteMapNode
    
            Dim node As SiteMapNode = SiteMap.CurrentNode
            If IsThisTheNodeToChange(node) Then
                node = node.Clone()
                node.Title = GetNodeTitle()
            End If
            Return node
    
        End Function
    
    End Class
    

    <asp:SiteMapDataSource ID="siteMapDataSource" runat="Server" ShowStartingNode="false" StartFromCurrentNode="false" StartingNodeOffset="1" />
    <asp:DropDownList ID="pageMenu" runat="Server" AutoPostBack="True" DataSourceID="siteMapDataSource" DataTextField="Title" DataValueField="Url" />
    

    事件不会对任何内容触发,因为当前节点是定义菜单的页面。因此,菜单显示的是物理站点地图文件中的无意义占位符标题,而不是正确的标题。

    -编写我自己的站点地图提供程序。我不想复制所有默认行为,所以我尝试从默认提供程序派生,如下所示。

    Public Class DynamicXmlSiteMapProvider
        Inherits XmlSiteMapProvider
    
        Private _dataFixedUp As Boolean = False
    
        Public Overrides Function GetChildNodes(ByVal node As SiteMapNode) As SiteMapNodeCollection
    
            Dim result As SiteMapNodeCollection = MyBase.GetChildNodes(node)
            If Not _dataFixedUp Then
                For Each childNode As SiteMapNode In result
                    FixUpNode(childNode)
                Next
            End If
            Return result
    
        End Function
    
        Private Sub FixUpNode(ByVal node As SiteMapNode)
    
            If IsThisTheNodeToChange(node) Then
                node.ReadOnly = False
                node.Title = GetNodeTitle()
                node.ReadOnly = True
                _dataFixedUp = True
            End If
    
        End Sub
    
    End Class
    

    GetChildNodes 在网站浏览时,似乎不经常被调用。

    -尝试在数据加载到内存中后立即修复数据,而不是在访问数据时。

    Public Class DynamicXmlSiteMapProvider
        Inherits XmlSiteMapProvider
    
        Private _dataFixInProgress As Boolean = False
        Private _dataFixDone As Boolean = False
    
        Public Overrides Function BuildSiteMap() As SiteMapNode
    
            Dim result As SiteMapNode = MyBase.BuildSiteMap()
            If Not _dataFixInProgress AndAlso Not _dataFixDone Then
                _dataFixInProgress = True
                For Each childNode As SiteMapNode In result.GetAllNodes()
                    FixUpNode(childNode)
                Next
                _dataFixInProgress = False
                _dataFixDone = True
            End If
            Return result
    
        End Function
    
        Private Sub FixUpNode(ByVal node As SiteMapNode)
    
            If IsThisTheNodeToChange(node) Then
                node.ReadOnly = False
                node.Title = GetNodeTitle()
                node.ReadOnly = True
            End If
    
        End Sub
    
    End Class
    

    这似乎奏效了。但是,我担心电话 GetAllNodes BuildSiteMap 构建网站地图

    -类似于第二次尝试,但压倒一切 全部 与读取数据有关的虚拟成员( CurrentNode , FindSiteMapNode , FindSiteMapNodeFromKey , GetChildNodes , GetCurrentNodeAndHintAncestorNodes , GetCurrentNodeAndHintNeighborhoodNodes , GetParentNode , GetParentNodeRelativeToCurrentNodeAndHintDownFromParent , GetParentNodeRelativeToNodeAndHintDownFromParent , HintAncestorNodes , HintNeighborhoodNodes

    这不起作用。我将调试语句放在所有被覆盖的成员中,似乎在数据绑定到下拉列表时根本没有调用它们。我能想到的唯一解释是,在 构建网站地图 呼叫,以便 SiteMapNode

    有人有更好的建议吗?

    4 回复  |  直到 16 年前
        1
  •  2
  •   Mark Redman    16 年前

        2
  •  1
  •   Rex M    16 年前
        3
  •  1
  •   Christian Hayter    16 年前

    Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
    
        ' Do this as early as possible in the page lifecycle so that it happens before any
        ' automatic data binding or control initialisation is done.
        Dim node As SiteMapNode = GetNodeToEdit()
        Dim nodeReadOnly As Boolean = node.ReadOnly
        node.ReadOnly = False
        node.Title = GetNodeTitle()
        node.ReadOnly = nodeReadOnly
    
    End Sub
    

    然而,我已经接受了马克的回答,因为如果将来需要进行更广泛的修改,我会这样做。

        4
  •  1
  •   Dan    14 年前

    感谢Christian的研究。根据你的结果,我提出了以下可能对他人有所帮助的建议:

    ' Dynamically update some menu items.
    '
    ' Since the correct Medical Center ID is not known until runtime, need to
    ' append "&MEDICAL_CENTER_ID=xxx" to all of the report's URLs in Web.sitemap.
    Public Shared Sub UpdateMenu(ByVal MedicalCenterID As String)
      Dim CurrentNodeTitle As String = ""
      Dim NodeReadOnlyProperty As Boolean
    
      ' Home menu item
      CurrentNodeTitle = SiteMap.CurrentNode.Title
    
      ' Determines if the current node has child nodes.
      If (SiteMap.CurrentNode.HasChildNodes) Then
        ' Loop through top level 1 menu items (looking for Reports)
        For Each ChildNodesEnumerator1 As SiteMapNode In SiteMap.CurrentNode.ChildNodes
          CurrentNodeTitle = ChildNodesEnumerator1.Title
          If CurrentNodeTitle = "Reports" Then
            ' Loop through level 2 menu items (looking for specfic reports)
            For Each ChildNodesEnumerator2 As SiteMapNode In ChildNodesEnumerator1.ChildNodes
              CurrentNodeTitle = ChildNodesEnumerator2.Title
              If CurrentNodeTitle = "Multi-Day Vehicle Requests" Or _
               CurrentNodeTitle = "XXXXXXXXXXXXXXXXX" Then
                ' First check if the URL has not been modified already
                If InStr(ChildNodesEnumerator2.Url, "MEDICAL_CENTER_ID") = 0 Then
                  NodeReadOnlyProperty = ChildNodesEnumerator2.ReadOnly
                  ChildNodesEnumerator2.ReadOnly = False
                  ChildNodesEnumerator2.Url = ChildNodesEnumerator2.Url & "&MEDICAL_CENTER_ID=" & MedicalCenterID
                  ChildNodesEnumerator2.ReadOnly = NodeReadOnlyProperty
                End If
              End If
            Next
          End If
        Next
      End If
    End Sub
    
    推荐文章