Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

C# type casting

Posted on 2006-06-22
13
Medium Priority
?
395 Views
Last Modified: 2012-08-13
Hi,
I am new to C# and have not done much object oriented programming. Nevertheless, I have to create a 3 level dynamic and scalable menu in .NET 1.2, C# and ASP. C# is used to build and draw the menu.
Basically I have to create two classes "Menu" and "MenuItem".
"Menu" is a class that will have "Name", "URL",  "Children" variables. "MenuItem" class will have "Name" and "URL" variables. "Children"  is a collection of "MenuItem" objects and/or "Menu" objects. The idea is to use polymorphism so that if menu has a child that has a child we are using "Menu".
Each aspx page has several variables that are read by the menu script to know which section to highlight in the menu.

I am getting an error

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidCastException: Specified cast is not valid.

Source Error:


Line 90:                   
Line 91:                   foreach(object m in this.ChildMenu )
Line 92:                   {      Menu menu = (Menu)m; //cast it back to Menu object
Line 93:                         //error handeling
Line 94:                         if(menu._childMenu != null)
 

Source File: C:\Inetpub\wwwroot\DIR006\dev\root\ontario\business\test2.aspx    Line: 92


here is the code


<%@ Page Language="c#" %>
<%@ Import namespace="System"%>
<%@ Import namespace="System.Collections"%>
<script language="c#" runat="server">

 
public class Menu
{
      
      //region private fields      
      private string _menuName;      
      private string _linkUrl;
      private int _menuLevel;      
      private ArrayList _childMenu;
      
      //private string _childMenu;
      //endregion

      public Menu(){
            this._menuName = "";
            this._linkUrl = "";
            this._menuLevel = 0;
            this._childMenu = new ArrayList();
      }//end Nav
      
      public Menu(string mName, string mUrl, int mLevel)
      {
            this._menuName = mName;
            this._linkUrl = mUrl;
            this._menuLevel = 0;
            this._childMenu = new ArrayList();
            
      
      }//end Nav
      
      public Menu(string mName, string mUrl, ArrayList chMenu, int mLevel )
      {
            this._menuName = mName;
            this._linkUrl = mUrl;
            this._menuLevel = mLevel;
            this._childMenu = chMenu;
      }//end Nav

      public string MenuName
      {
            get { return _menuName; }
            set { _menuName = value; }
      }

      
      public string LinkUrl
      {
            get { return _linkUrl; }
            set { _linkUrl = value; }
      }
      
      public int MenuLevel
      {
            get { return _menuLevel; }
            set { _menuLevel = value; }
      }
      
      public ArrayList ChildMenu
      {
            get { return _childMenu; }
            set { _childMenu = value; }
      }
      
            
      public string printMenu()
      {      
            string menuNav = "";
            
            
            //build menu with no subsection
            if(this._childMenu == null)
            {
                  if(this._childMenu[0] is MenuItem)
                  {            
                        //loop through the menuItems. create menues without subsections            
                        foreach(MenuItem item in this.ChildMenu )
                        {      
                              menuNav += "<div id=\"menu_level" + item.MenuLevel + "\">" + item.printMenuItem().ToString() + "</div>";                                          
                        }
                        
                  }
            }
            else   /// menu with subsections
            {
                  
                  foreach(object m in this.ChildMenu )
                  {      Menu menu = (Menu)m; //cast it back to Menu object
                        //error handeling
                        if(menu._childMenu != null)
                        {                        
                              foreach(object sM in menu.ChildMenu )
                              {
                                    Menu subMenu = (Menu)sM; //cast it back to Menu object
                                    if(subMenu._childMenu != null)
                                    {                        
                                          foreach(object sCh in subMenu.ChildMenu)
                                          {
                                                Menu subChild = (Menu)sCh; //cast it back to Menu object
                                                menuNav += "<div id=\"menu_level" + subChild.MenuLevel + "\">" + subChild.printMenu().ToString() + "</div>";
                                          }                              
                                    }
                              }      
                        }
                        else
                        {
                              menuNav += "this menu should be using MenuItem object";
                        }
                  }
                        
            }
            
            return menuNav;      
            
      }
      
      //pint menues that have subsections
      public string drawNav()
      {                  
            return this.printMenu();            
                  
      }
      
      
      
      ///
      
      
      
}

///////////////////////////MenuItem//////////////////////////////////////////////////////
public class MenuItem
{
      private string _menuName;      
      private string _linkUrl;      
      private int _menuLevel;
      private ArrayList _childMenu;
      
      //endregion

      
      public MenuItem(){
            this._menuName = "";
            this._linkUrl = "";
            this._menuLevel = 0;
      }//end Nav
      
      public MenuItem(string mName, string mUrl, int mLevel){
            this._menuName = mName;
            this._linkUrl = mUrl;
            this._menuLevel = mLevel;
            
      }//end Nav
      
      //get and set
      public string MenuName
      {
            get { return _menuName; }
            set { _menuName = value; }
      }

      
      public string LinkUrl
      {
            get { return _linkUrl; }
            set { _linkUrl = value; }
      }
      
      public int MenuLevel
      {
            get { return _menuLevel; }
            set { _menuLevel = value; }
      }
      
      ///print items
      public string printMenuItem()
      {      
            string menuNav = "";            
            
            //menuNav += "<div id=\"menu_level2\">";
            menuNav += "<a href=\"" + this._linkUrl + "?WT.svl=nav\">" + this._menuName + "</a>";            
            //menuNav +=  + "</div>";
                        
            return menuNav;
      }      
      
      
}



</script>

<body>
<div id="main">
<%


MenuItem oMenuItem = new MenuItem();
Menu oMenu = new Menu();

//direct Energy Business srvices section
oMenuItem = new MenuItem("Business Services","/ontario/business/default.aspx",1);
oMenu.ChildMenu.Add(oMenuItem);


//Doing Business with Direct Energy section
oMenuItem = new MenuItem("Consultative Process","/ontario/business/business_with_direct/consultive_process.aspx",2);
oMenu = new Menu("Doing Business","/ontario/business/business_with_direct/default.aspx",1);
oMenu.ChildMenu.Add(oMenuItem);

            
Response.Write("<div style=\"width:146px;\">");
Response.Write("" + oMenu.drawNav());
Response.Write("</div>");

%>
</div>
</body>
0
Comment
Question by:ashevel
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 2
13 Comments
 
LVL 11

Expert Comment

by:vo1d
ID: 16964247
this.ChildMenu is of type arraylist, not of type Menu.

you declared it here:

private ArrayList _childMenu;

public ArrayList ChildMenu
     {
          get { return _childMenu; }
          set { _childMenu = value; }
     }

you will have to cast it to arraylist:
foreach(object m in this.ChildMenu )
{     ArrayList menu = (ArrayList )m;
      //error handeling
      if(menu._childMenu != null)
     

to loop through all your chidmenues, i would recommend a recursive method for that.
0
 

Author Comment

by:ashevel
ID: 16964577
foreach(object m in this.ChildMenu )
{     ArrayList menu = (ArrayList )m;
      //error handeling
      if(menu._childMenu != null)
 

 I get an error :

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error Message: CS0117: 'System.Collections.ArrayList' does not contain a definition for 'MenuLevel'

Source Error:

 

Line 104:                        
Line 105:                        
Line 106:                        menuNav += "<div id=\"menu_level" + menu.MenuLevel + "\">" + menu.printMenu().ToString() + "</div>";
Line 107:                        if(menu._childMenu != null)
Line 108:            
 
     
0
 

Author Comment

by:ashevel
ID: 16964599
ArrayLists contains objects that have parameters that I need to access. so I need to declare object handl some how to get access to parameters in array list
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 11

Expert Comment

by:vo1d
ID: 16964608
no it cant have such a property, because the field menu is of type arraylist and not of type Menu.
why do you use an arraylist?
it only makes sense, if you add more than one Menu instance to it.
0
 

Author Comment

by:ashevel
ID: 16964633
that's the idea. I am adding more instanses of Manu and MenuItem to the array list.
0
 

Author Comment

by:ashevel
ID: 16964690
I am using polymorphism and recurcive method... this is sort of the idea.
//first level
Menu
  Name: "Menu1"
  Url: "www.link.com"
  Children:
              //second level
               MenuItem:
                    Name: "ChildMenu1"
                    URL: "www.link.com"

               Menu:
                    Name: "ChildMenu2'
                    URL: "....."
                    Children:
                    //third level
                                MenuItem:
                                    Name: "Childmenu4"
                                    Url: "...."
//first level
MenuItem
  Name: "Menu1"
  Url: "www.link.com"
  Children:

//first level
Menu
  Name: "Menu1"
  Url: "www.link.com"
  Children:
              //second level
               MenuItem:
                    Name: "ChildMenu1"
                    URL: "www.link.com"
             
0
 
LVL 3

Expert Comment

by:Bowmanje
ID: 16968986
ashevel,

In order to use polymorphism, both classes need to derive from a base class.  In this case, it would seem appropriate to derive Menu from MenuItem since it is both an item in its parent's menu as well as a menu itself.  Since neither class appears to extend a common base class and you add all your items to the arraylist as MenuItem, the cast to Menu is invalid. Try this...

class Menu : MenuItem
{
   ...
}

Additionally, you do not need to declare MenuName, LinkUrl, ChildMenu, or MenuLevel properties in Menu, since they are already declared in MenuItem.

HTH,
Josh
0
 
LVL 3

Expert Comment

by:Bowmanje
ID: 16969131
Oh, in my previous post, either your private fields would need to be declared protected, or you would need to redo you constructors. Such as...

public Menu(string mName, string mUrl, ArrayList chMenu, int mLevel ) : base(mName, mUrl, chMenu, mLevel)
     {
         
     }//end Nav

-Josh
0
 

Author Comment

by:ashevel
ID: 16969591
"you add all your items to the arraylist as MenuItem, the cast to Menu is invalid. "
Bowmanje,
I will aslo have to add items to the arraylist as Menu if the menu has children. Menu is the the class that has arrayList. the code I provided was somewhat incomplete...
for example:

MenuItem oMenuItem = new MenuItem();
Menu oMenu = new Menu();

// section1
oMenu = new Menu("Business Services","/ontario/business/default.aspx",1);
oMenu.ChildMenu.Add(oMenu);

//section2
oMenu = new Menu("Doing Business","/ontario/business/business/default.aspx",1);
oMenuItem = new MenuItem("Consultative Process","/ontario/business/business_with_direct/consultive_process.aspx",2);

oMenu.ChildMenu.Add(oMenuItem);
oMenu.ChildMenu.Add(oMenu);

//section3
MenuItem oSubMenu = MenuItme;
oMenu = new Menu("blah","/ontario/business/business/default.aspx",1);
oSubMenu = new Menu("blablah","/ontario/business/business_direct/process.aspx",2);
oMenuItem = new MenuItem("Menu Level3","/ontario/business/business_with_direct/consultive_process.aspx",3);

oSubMenu.ChildMenu.Add(oMenuItem);
oMenu.ChildMenu.Add(oSubMenu);
oMenu.ChildMenu.Add(oMenu);
0
 
LVL 11

Accepted Solution

by:
vo1d earned 2000 total points
ID: 16970943
to my opinion, your design has a failure.
it is not a good way to store two different types in the same arraylist.

you should setup a different design:
every entry is of type menutitem which has a reference to its parent menuitem and an arraylist(better would be an own menuitem collection) with subitems.
these subitems are also menuitems.

so your object design should look like similar to this(its hacked in this experts-exchange textbox and is NOT tested -> its only to push you in the correct direction):
public class MenuItem
{
     //region private fields    
     private Menuitem _parentMenuItem;
     private string       _menuTitle;    
     private string       _linkUrl;
     private int            _menuLevel;    
     private ArrayList   _subMenuItems;

     public MenuItem(string MenuTitle, string mUrl, int mLevel, MenuItem parentMenuItem)
     {
          this._menuName         = MenuTitle;
          this._linkUrl                = mUrl;
          this._menuLevel          = mLevel;
          this._parentMenuItem = parentMenuItem
          this._subMenuItems    = new ArrayList();        
     }    
     //get and set
     public string MenuName
     {
          get { return _menuName; }
          set { _menuName = value; }
     }

     
     public string LinkUrl
     {
          get { return _linkUrl; }
          set { _linkUrl = value; }
     }
     
     public int MenuLevel
     {
          get { return _menuLevel; }
          set { _menuLevel = value; }
     }
     
     public MenuItem ParentMenuItem
     {
          get { return _parentMenuItem; }
          set { _parentMenuItem= value; }
     }

      public ArrayList SubMenuItems
     {
          get { return _subMenuItems; }
     }
     ///print items
     public string printMenuItem()
     {    
          string menuNav = "";          
         
          //menuNav += "<div id=\"menu_level2\">";
          menuNav += "<a href=\"" + this._linkUrl + "?WT.svl=nav\">" + this._menuName + "</a>";          
          //menuNav +=  + "</div>";
                   
          return menuNav;
     }  

     //add a submenuitem
    public MenuItem AddSubMenuItem(string MenuTitle, string mUrl)
    {
       MenuItem newItem = new MenuItem(MenuTitle, mUrl, this._menuLevel+1, this)
       this._subMenuItems.Add(newItem);
       return(newItem);
    }
   
    //get a submenuitem
    public MenuItem GetSubMenuItem(int index)
    {
       return(index < this._subMenuItems.Count ? this._subMenuItems[index] : null);
    }

    public MenuItem GetSubMenuItem(string SubMenuTitle)
    {
       foreach(MenuItem currentItem in this._subMenuItems)
       {
         if(currentItem._menuName == SubMenuTitle)
         {
           return (currentItem);
         }
       }
       return (null);
   }
}


now you can make something like this:

MenuItem mainMenuItem1 = new MenuItem("Menu1", "www.link.com", 0, null);
mainMenuItem1.AddSubMenuItem("ChildMenu1", "www.link.com"); //will automatically level1 and has parent mainMenuItem
MenuItem subMenuItemOfMainMenuItem1 = mainMenuItem1.AddSubMenuItem("ChildMenu2", "www.link.com") //will also have level1 and parent mainMenuItem
subMenuItemOfMainMenuItem1.AddSubMenuItem("Childmenu4", "www.link.com"); //will automatically level2 and has parent subMenuItemOfMainMenuItem1

that tree would look like this:

Menu1
    ChildMenu1
    ChildMenu2
        ChildMenu4


0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Najam
Having new technologies does not mean they will completely replace old components.  Recently I had to create WCF that will be called by VB6 component.  Here I will describe what steps one should follow while doing so, please feel free to post any qu…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses

715 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question