+ Reply to Thread
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 15

Thread: VB.Net Dynamic Recursive Menu

  1. #1
    The Barnfather jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead's Avatar
    Join Date
    Mar 2008
    Location
    Reston, VA
    Posts
    4,547
    Blog Entries
    9
    Real Name
    Jason
    Rep Power
    22

    VB.Net Dynamic Recursive Menu

    I got this idea from helping another member with some similar code. This uses the Menu Class to build a menu a populates it from a database, allowing for multiple child menus. Sample files are included.
    Menu.aspx
    Code:
    <%@ Page Language="VB" AutoEventWireup="false" CodeFile="menu.aspx.vb" Inherits="_Menu"%>
    <html>
    <head>
        <title>Recursive Menu Example</title>
    </head>
        <body>
            <form id="Form1" runat="server">
                <asp:Panel ID="Panel1" runat="server" />
            </form>
        </body>
    </html>
    
    menu.aspx.vb
    Code:
    Imports System.Data.OleDb
    Partial Class _Menu
        Inherits System.Web.UI.Page
        '//Connection to database from web.config file
        Private conn As New OleDbConnection(ConfigurationManager.ConnectionStrings("menu").ConnectionString)
        Private Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
            Call PopulateMenu()
        End Sub
        Private Sub PopulateMenu()
            Try
                '//Define new menu
                Dim menu As New Menu()
                '//Retrieve menu data
                Dim menuData As DataTable = GetMenuData()
                AddTopMenuItems(menuData, menu)
                Me.Panel1.Controls.Add(menu)
                Me.Panel1.DataBind()
            Catch ex As Exception
                Response.Write(ex.Message.ToString() & "<br />")
            End Try
        End Sub
        Private Function GetMenuData() As DataTable
            Try
                '//Populate DataTable
                Dim strSQL As String = "SELECT * FROM tbl_menu"
                Dim datMenu As OleDbDataAdapter = New OleDbDataAdapter(strSQL, conn)
                Dim tblMenu As DataTable = New DataTable()
                datMenu.Fill(tblMenu)
                Return tblMenu
            Catch ex As Exception
                Response.Write(ex.Message.ToString() & "<br />")
            End Try        
        End Function
        Private Sub AddTopMenuItems(ByVal menuData As DataTable, ByVal menu As Menu)
            Try
                '//Populate DataView
                Dim datView As DataView = New DataView(menuData)
                '//Filter parent menu items
                datView.RowFilter = "parentid = 0"
                '//Populate menu with top menu items
                Dim datRow As DataRowView
                For Each datRow In datView
                    '//Define new menu item
                    Dim parentMenu As MenuItem
                    parentMenu = CreateMenuItem(datRow("linktext"), datRow("linkurl"), datRow("linktext"))
                    menu.Items.Add(parentMenu)
                    '//Populate child items of this parent
                    AddChildMenuItems(menuData, datRow("itemid"), parentMenu)
                Next
            Catch ex As Exception
                Response.Write(ex.Message.ToString() & "<br />")
            End Try
        End Sub
        Private Sub AddChildMenuItems(ByVal menuData As DataTable, ByVal parentID As Integer, Byval parentMenu As MenuItem)
            Try
                '//Populate DataView
                Dim datView As DataView = New DataView(menuData)
     
                '//Filter child menu items
                datView.RowFilter = "parentid = " & parentID
                '//Populate parent menu item with child menu items
                Dim datRow As DataRowView
                For Each datRow in datView
                    '//Define new menu item
                    Dim childMenu As MenuItem
                    childMenu = CreateMenuItem(datRow("linktext"), datRow("linkurl"), datRow("linktext"))
                    parentMenu.ChildItems.Add(childMenu)
                    '//Populate child items of this parent
                    AddChildMenuItems(menuData, datRow("itemid"), childMenu)
                Next
            Catch ex As Exception
                Response.Write(ex.Message.ToString() & "<br />")
            End Try
        End Sub
        Private Function CreateMenuItem(ByVal strText As String, ByVal strUrl As String, ByVal strToolTip As String) As MenuItem
            Try
                '//Create new menu item
                Dim menuItem As New menuItem()
                '//Set properties of the menu item
                With menuItem
                    .Text = strText
                    .NavigateUrl = strUrl
                    .ToolTip = strToolTip
                End With
                Return menuItem
            Catch ex As Exception
                Response.Write(ex.Message.ToString() & "<br />")
            End Try        
        End Function
    End Class
    
    Untested C# - I haven't tested this as I'm not a C# coder...if anyone has any issues with this, let me know:
    Code:
    using System.Data.OleDb;
    partial class _Menu : System.Web.UI.Page
    {
        ////Connection to database from web.config file
        private OleDbConnection conn = new OleDbConnection(ConfigurationManager.ConnectionStrings("menu").ConnectionString);
        private void Page_Load(object sender, EventArgs e)
        {
            PopulateMenu();
        }
        private void PopulateMenu()
        {
            try {
                ////Define new menu
                Menu menu = new Menu();
                ////Retrieve menu data
                DataTable menuData = GetMenuData();
                AddTopMenuItems(menuData, menu);
                this.Panel1.Controls.Add(menu);
                this.Panel1.DataBind();
            }
            catch (Exception ex) {
                Response.Write(ex.Message.ToString() + "<br />");
            }
        }
        private DataTable GetMenuData()
        {
            try {
                ////Populate DataTable
                string strSQL = "SELECT * FROM tbl_menu";
                OleDbDataAdapter datMenu = new OleDbDataAdapter(strSQL, conn);
                DataTable tblMenu = new DataTable();
                datMenu.Fill(tblMenu);
                return tblMenu;
            }
            catch (Exception ex) {
                Response.Write(ex.Message.ToString() + "<br />");
            }
        }
        private void AddTopMenuItems(DataTable menuData, Menu menu)
        {
            try {
                ////Populate DataView
                DataView datView = new DataView(menuData);
                ////Filter parent menu items
                datView.RowFilter = "parentid = 0";
                ////Populate menu with top menu items
                DataRowView datRow = default(DataRowView);
                foreach ( datRow in datView) {
                    ////Define new menu item
                    MenuItem parentMenu = default(MenuItem);
                    parentMenu = CreateMenuItem(datRow("linktext"), datRow("linkurl"), datRow("linktext"));
                    menu.Items.Add(parentMenu);
                    ////Populate child items of this parent
                    AddChildMenuItems(menuData, datRow("itemid"), parentMenu);
                }
            }
            catch (Exception ex) {
                Response.Write(ex.Message.ToString() + "<br />");
            }
        }
        private void AddChildMenuItems(DataTable menuData, int parentID, MenuItem parentMenu)
        {
            try {
                ////Populate DataView
                DataView datView = new DataView(menuData);
                
                ////Filter child menu items
                datView.RowFilter = "parentid = " + parentID;
                ////Populate parent menu item with child menu items
                DataRowView datRow = default(DataRowView);
                foreach ( datRow in datView) {
                    ////Define new menu item
                    MenuItem childMenu = default(MenuItem);
                    childMenu = CreateMenuItem(datRow("linktext"), datRow("linkurl"), datRow("linktext"));
                    parentMenu.ChildItems.Add(childMenu);
                    ////Populate child items of this parent
                    AddChildMenuItems(menuData, datRow("itemid"), childMenu);
                }
            }
            catch (Exception ex) {
                Response.Write(ex.Message.ToString() + "<br />");
            }
        }
        private MenuItem CreateMenuItem(string strText, string strUrl, string strToolTip)
        {
            try {
                ////Create new menu item
                menuItem menuItem = new menuItem();
                ////Set properties of the menu item
                {
                    menuItem.Text = strText;
                    menuItem.NavigateUrl = strUrl;
                    menuItem.ToolTip = strToolTip;
                }
                return menuItem;
            }
            catch (Exception ex) {
                Response.Write(ex.Message.ToString() + "<br />");
            }
        }
    }
    
    Table design:
    This setup uses a table with the following field types:
    itemid - AutoNumber
    parentid - Number
    linktext - Text
    linkurl - Text
    Parent items will have parentid = 0 whereas child items will have parentid = itemid of the parent.
    Attached Files
    jmurrayhead
    If you agree, give me rep.
    If you like it here...throw us a few bones to help support us.


  2. #2
    Barn Newbie yiffzer is an unknown quantity at this point yiffzer's Avatar
    Join Date
    Feb 2010
    Posts
    2
    Rep Power
    2

    I tried testing this in VS2008 but had errors. Nothing worked. This seemed to be my last hope of solving this complex dynamic navigation list. I'm at loss, really.

  3. #3
    The Barnfather jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead's Avatar
    Join Date
    Mar 2008
    Location
    Reston, VA
    Posts
    4,547
    Blog Entries
    9
    Real Name
    Jason
    Rep Power
    22

    Did you receive any error messages?
    jmurrayhead
    If you agree, give me rep.
    If you like it here...throw us a few bones to help support us.


  4. #4
    Barn Newbie yiffzer is an unknown quantity at this point yiffzer's Avatar
    Join Date
    Feb 2010
    Posts
    2
    Rep Power
    2

    Before even running it, a bunch of warnings/errors came up:


  5. #5
    The Barnfather jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead's Avatar
    Join Date
    Mar 2008
    Location
    Reston, VA
    Posts
    4,547
    Blog Entries
    9
    Real Name
    Jason
    Rep Power
    22

    If using VB, add this to the top of the page:
    Code:
    Imports System.Data
    
    If using C#, add this to the top:
    Code:
    using System.Data;
    
    jmurrayhead
    If you agree, give me rep.
    If you like it here...throw us a few bones to help support us.


  6. #6
    Barn Newbie tomhawk is an unknown quantity at this point tomhawk's Avatar
    Join Date
    May 2010
    Posts
    1
    Rep Power
    2

    Thanks alot

    Thanks alot

  7. #7
    Wolfmaster Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy's Avatar
    Join Date
    Mar 2008
    Location
    Peoria, IL
    Posts
    2,386
    Blog Entries
    5
    Real Name
    Wolff
    Rep Power
    15

    The reason for the warnings you are getting is that if the CreateMenuItem (for example) fails and throws and exception, no return statement is being executed. However, in looking at this method, I wonder about the necessity of adding the overhead of exception handling since the only thing it is doing is instantiating a MenuItem and setting some properties. The method consumes the exception and thus the calling method would have no way of knowing that the CreateMenuItem failed -- and it would happily continue on and throw a NullReferenceException at some point. Personally I would remove the try..catch block from CreateMenuItem because (1) this is a private method and thus it won't be used by developers; we can handle the errors within the class and (2) it is very unlikely that it would throw an exception, given the instructions being executed.

    If you really want to handle the exception here to generate the error message as some HTML (as in the example), that's fine -- however I would either then rethrow the exception or place a return null (or return nothing) statement outside the try...catch block and then check for a null in the calling method. Rethrowing the exception is valid since the exception is not handled in a way that would allow execution to continue and thus could/should be handled higher up in the stack.
    Wolffy
    .-- ----- ..-. ..-. -.--
    Opinions expressed are my own and do not necessity reflect those of any sane person. Any code provided is intended to be an example and is provided AS IS. Void where prohibited by law. Not valid in California. Your mileage may vary.

  8. #8
    The Barnfather jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead's Avatar
    Join Date
    Mar 2008
    Location
    Reston, VA
    Posts
    4,547
    Blog Entries
    9
    Real Name
    Jason
    Rep Power
    22

    I admit that this isn't the best error handling as I wrote this a few years ago...but there isn't any overhead of using Try...Catch unless there is actually an exception.

    When I have spare time, I plan on improving the coding method and making this a server control, where people can simply add reference to the dll and use it like any other control.
    jmurrayhead
    If you agree, give me rep.
    If you like it here...throw us a few bones to help support us.


  9. #9
    Wolfmaster Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy is a splendid one to behold Wolffy's Avatar
    Join Date
    Mar 2008
    Location
    Peoria, IL
    Posts
    2,386
    Blog Entries
    5
    Real Name
    Wolff
    Rep Power
    15

    I'm going to conditionally disagree in that Try...Catch does add overhead in setting up the exception stack -- however, I make it conditional until I get my computer here (oh when..oh when) and can look at the MSIL being generated.
    Wolffy
    .-- ----- ..-. ..-. -.--
    Opinions expressed are my own and do not necessity reflect those of any sane person. Any code provided is intended to be an example and is provided AS IS. Void where prohibited by law. Not valid in California. Your mileage may vary.

  10. #10
    The Barnfather jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead has much to be proud of jmurrayhead's Avatar
    Join Date
    Mar 2008
    Location
    Reston, VA
    Posts
    4,547
    Blog Entries
    9
    Real Name
    Jason
    Rep Power
    22

    Quote from MSDN:
    Finding and designing away exception-heavy code can result in a decent perf win. Bear in mind that this has nothing to do with try/catch blocks: you only incur the cost when the actual exception is thrown. You can use as many try/catch blocks as you want. Using exceptions gratuitously is where you lose performance. For example, you should stay away from things like using exceptions for control flow.
    Performance Tips and Tricks in .NET Applications

    unless I'm misunderstanding something here?
    jmurrayhead
    If you agree, give me rep.
    If you like it here...throw us a few bones to help support us.


+ Reply to Thread
Page 1 of 2 1 2 LastLast

Similar Threads

  1. Creating Dynamic Dropdown Menu!?
    By jarvelous in forum ASP Development
    Replies: 1
    Last Post: March 20th, 2008, 01:30 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

SEO by vBSEO