Code snippet: Optimise output size when using programmatically generated Context Menus

1 posts, 0 answers
  1. Alex Norcliffe
    Alex Norcliffe avatar
    73 posts
    Member since:
    Dec 2004

    Posted 17 Jul 2006 Link to this post

    Requirements

    r.a.d.treeview
    version

    5.4
    .NET version

    1.0, 1.1 and 2.0
    Visual Studio version N/A
    programming language

    VB.NET & C#
    browser support

    all browsers supported by r.a.d.treeview


     
    PROJECT DESCRIPTION
    A code snippet which you can paste into your TreeView binding logic if you use a lot of programmatically-generated Context Menus.

    Consider the following scenario: You have a TreeView containing 100 nodes spread across 5 levels. Each node represents a file or folder on the server filesystem. You already have your own code to bind the TreeView, and each node also has a Context Menu created which represents the actions that the user has permission to perform. One file node to which the user has full access may have a complete Context Menu including 'Edit' and 'Rename', whilst another node may only have 'View' because of restricted permissions.

    In this scenario, you are assigning an ID and Text values to the Context Menu items in order that you can ascertain which item has been clicked upon postback.

    Due to differing nodes having the same permissions, the TreeView's HTML output will contain duplicate declarations of effectively the 'same' Context Menu.

    Solution

    It can be reasonably expected that a list of all the IDs that the Context Menu contains, in order, forms a unique reference that uniquely identifies the contents of that menu.

    So, the proposal is to name your menus with this list of IDs. Each time you add a new Context Menu to the TreeView.ContextMenus collection, you first check that collection for an item with the same name and if it exists you don't add it.

    For instance if your Context Menu items are:

    ID=0, Text=Create New
    ID=1, Text=Edit
    ID=2, Text=Delete
    ID=3, Text=View

    Any menus that have al four items could be given the name:

    0|1|2|3

    ...since the name is only used internally. A menu with just 'View' might have the name:

    3

    The following function will generate the name for you:

    VB.NET
        Function GenerateMenuName(ByVal cmi As ContextMenu) As String
            Dim nameBuilder As New System.Text.StringBuilder
            For Each menuItem As ContextMenuItem In cmi.Items
                nameBuilder.Append(menuItem.ID)
                nameBuilder.Append("|")
            Next
            Return nameBuilder.ToString().TrimEnd("|"c)
        End Function

    The following function will check the collection for you and tell you if you should add it:

        Function CheckMenuExists(ByVal c As ContextMenu, ByVal tv As RadTreeView) As Boolean
            For Each cMenu As ContextMenu In tv.ContextMenus
                If String.Compare(cMenu.Name, c.Name, True) = 0 Then
                    Return True
                End If
            Next
            Return False
        End Function


    Finally, the following function will use the previous two and you can drop this into your existing binding logic in place of any calls to TreeView.ContextMenus.Add()

        Sub AutoAddMenu(ByVal node As RadTreeNode, ByVal cm As ContextMenu)
            Dim name As String = GenerateMenuName(cm)
            If Not CheckMenuExists(cm, node.TreeViewParent) Then
                node.TreeViewParent.ContextMenus.Add(cm)
            End If
            node.ContextMenuName = name
        End Sub
Back to Top