Link to home
Start Free TrialLog in
Avatar of ashevel
ashevel

asked on

C# type casting

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>
Avatar of vo1d
vo1d
Flag of Germany image

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.
Avatar of ashevel
ashevel

ASKER

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:            
 
     
Avatar of ashevel

ASKER

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
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.
Avatar of ashevel

ASKER

that's the idea. I am adding more instanses of Manu and MenuItem to the array list.
Avatar of ashevel

ASKER

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"
             
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
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
Avatar of ashevel

ASKER

"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);
ASKER CERTIFIED SOLUTION
Avatar of vo1d
vo1d
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial