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.InvalidCastExceptio n: 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\o ntario\bus iness\test 2.aspx Line: 92
here is the code
<%@ Page Language="c#" %>
<%@ Import namespace="System"%>
<%@ Import namespace="System.Collecti ons"%>
<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().ToStr ing() + "</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().ToStr ing() + "</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/busine ss/default .aspx",1);
oMenu.ChildMenu.Add(oMenuI tem);
//Doing Business with Direct Energy section
oMenuItem = new MenuItem("Consultative Process","/ontario/busines s/business _with_dire ct/consult ive_proces s.aspx",2) ;
oMenu = new Menu("Doing Business","/ontario/busine ss/busines s_with_dir ect/defaul t.aspx",1) ;
oMenu.ChildMenu.Add(oMenuI tem);
Response.Write("<div style=\"width:146px;\">");
Response.Write("" + oMenu.drawNav());
Response.Write("</div>");
%>
</div>
</body>
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.InvalidCastExceptio
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\
here is the code
<%@ Page Language="c#" %>
<%@ Import namespace="System"%>
<%@ Import namespace="System.Collecti
<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().ToStr
}
}
}
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().ToStr
}
}
}
}
else
{
menuNav += "this menu should be using MenuItem object";
}
}
}
return menuNav;
}
//pint menues that have subsections
public string drawNav()
{
return this.printMenu();
}
///
}
//////////////////////////
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/busine
oMenu.ChildMenu.Add(oMenuI
//Doing Business with Direct Energy section
oMenuItem = new MenuItem("Consultative Process","/ontario/busines
oMenu = new Menu("Doing Business","/ontario/busine
oMenu.ChildMenu.Add(oMenuI
Response.Write("<div style=\"width:146px;\">");
Response.Write("" + oMenu.drawNav());
Response.Write("</div>");
%>
</div>
</body>
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.ArrayL ist' 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:
{ 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.ArrayL
Source Error:
Line 104:
Line 105:
Line 106: menuNav += "<div id=\"menu_level" + menu.MenuLevel + "\">" + menu.printMenu().ToString(
Line 107: if(menu._childMenu != null)
Line 108:
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.
why do you use an arraylist?
it only makes sense, if you add more than one Menu instance to it.
ASKER
that's the idea. I am adding more instanses of Manu and MenuItem to the array list.
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"
//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
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
public Menu(string mName, string mUrl, ArrayList chMenu, int mLevel ) : base(mName, mUrl, chMenu, mLevel)
{
}//end Nav
-Josh
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/busine ss/default .aspx",1);
oMenu.ChildMenu.Add(oMenu) ;
//section2
oMenu = new Menu("Doing Business","/ontario/busine ss/busines s/default. aspx",1);
oMenuItem = new MenuItem("Consultative Process","/ontario/busines s/business _with_dire ct/consult ive_proces s.aspx",2) ;
oMenu.ChildMenu.Add(oMenuI tem);
oMenu.ChildMenu.Add(oMenu) ;
//section3
MenuItem oSubMenu = MenuItme;
oMenu = new Menu("blah","/ontario/busi ness/busin ess/defaul t.aspx",1) ;
oSubMenu = new Menu("blablah","/ontario/b usiness/bu siness_dir ect/proces s.aspx",2) ;
oMenuItem = new MenuItem("Menu Level3","/ontario/business /business_ with_direc t/consulti ve_process .aspx",3);
oSubMenu.ChildMenu.Add(oMe nuItem);
oMenu.ChildMenu.Add(oSubMe nu);
oMenu.ChildMenu.Add(oMenu) ;
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/busine
oMenu.ChildMenu.Add(oMenu)
//section2
oMenu = new Menu("Doing Business","/ontario/busine
oMenuItem = new MenuItem("Consultative Process","/ontario/busines
oMenu.ChildMenu.Add(oMenuI
oMenu.ChildMenu.Add(oMenu)
//section3
MenuItem oSubMenu = MenuItme;
oMenu = new Menu("blah","/ontario/busi
oSubMenu = new Menu("blablah","/ontario/b
oMenuItem = new MenuItem("Menu Level3","/ontario/business
oSubMenu.ChildMenu.Add(oMe
oMenu.ChildMenu.Add(oSubMe
oMenu.ChildMenu.Add(oMenu)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.