Introduction
Switching language of a menu is very useful for most applications. Nowadays, applications allow you to change your old menu automatically and dynamically. With some experiences of XML - a standard format for data storage, I wrote a small program to demo the switching of language in a menu. To use this code, you do not need to modify the code, you only modify the XML file (a file that stores information in your menu.)
Background
In this article, I used MS Visual Studio .NET Tools, technologies of .NET and XML. To understand this code, you need to have some basics on XML and C#. Besides, you must refer to BFS algorithms and the Queue data structure, I used these to find each item in the XML file.
Using the Code
First, I declared variables mnuMainMenu
and max
. mnuMainMenu
is the MainMenu
which is plugged into a program at run-time, max
is the max size of the Queue I use to store MenuItem
s.
private MainMenu mnuMainMenu = new MainMenu();
private int max = 100;
When the Form loads, I add language options to my ComboBox
[cboLanguage
] that stores language information. First, I declare an array of string
s, which includes three languages: Vietnamese, English and French. You can also add other languages. Then I add it into ComboxBox
by using the AddRange
method.
string[] language = {"Vietnamese","English","French"};
cboLanguage.Items.AddRange(language);
When a user chooses a language, I call the function loadMenu
with a parameter _language
. First, I check whether file LanguageMenu.xml already exists or not. I declare an object of DirectoryInfo
class named d
. The constructor of DirectoryInfo
class includes a path to the application. Then, I declare an array of FileSystemInfo f
, it receives all files and folders within the path.
Then I use a loop to check whether LanguageMenu.xml exists by comparing the name of the current file and the string
"LanguageMenu.xml
". If true
, I get a path of that file and initiate the variable exist to true
.
Then I declare an XmlDocument
object named doc
, and loads the XML file with the method Load
. I declare an object of XmlNode
named root
, that is a root of my XML document.
Then I use a loop to find a child node of the root that has the same language the user chose by using the command:
string language = node.Attributes[ "language"].InnerText;
After finding the language, I call the function CreateMenu
with parameter node
(node
is a current node I already found). This function will create a menu of the application. When function execution is complete, I break out of a loop and plug it into the application.
private void loadMenu(string _language)
{
DirectoryInfo d = new DirectoryInfo(Application.StartupPath);
FileSystemInfo[] f = d.GetFileSystemInfos();
string path = "";
bool exist = false;
foreach(FileSystemInfo f1 in f)
{
if(f1.Name.ToString() == "LanguageMenu.xml")
{
path = f1.FullName.ToString().Trim();
exist = true;
break;
}
}
if(exist)
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode root = doc.DocumentElement;
for(int j = 0 ; j < root.ChildNodes.Count ; j++)
{
XmlNode node = root.ChildNodes.Item(j);
string language = node.Attributes["language"].InnerText;
if
(language == _language)
{
CreateMenu(node);
break;
}
}
this.Menu = mnuMainMenu;
}
else
{
MessageBox.show("File LanguageMenu.xml does not exist");
}
}
After finding the node which will be the beginning of the menu, I call the function CreateMenu
, which accepts a parameter of type XmlNode
. In this code, I used BFS algorithms with the Queue
data structure to store all menu items. First, I declare a variable:
int first = 1 , last = 0 , bac = 0;
XmlNode[] queue = new XmlNode[max];
where first
is the front of my variable queue
, last
is the tail of queue
, and bac
is the level of the current MenuItem
. I also declare an array of XMLNode
type, named queue
, which has the structure of queue (a structure which follows FIFO rules).
The main function of my program is CreateMenu
, this function accepts a node typed XmlNode
. By using this node, the function will create a menu. Detailed code is shown below:
private void CreateMenu(XmlNode node)
{
int first = 1 , last = 0 , bac = 0;
XmlNode[] queue = new XmlNode[max];
last ++;
queue[last] = node;
while(first <= last)
{
XmlNode temp = queue[first++];
MenuItem[] mnuItem = new MenuItem[temp.ChildNodes.Count];
if(temp.ChildNodes.Count == 0) continue;
for(int j = 0 ; j < temp.ChildNodes.Count ; j++)
{
XmlNode child = temp.ChildNodes.Item(j);
string s = child.Attributes["value"].InnerText;
bac = Convert.ToInt32(child.Attributes["level"].InnerText);
mnuItem[j] = new MenuItem(s,new System.EventHandler(mnuClick));
queue[++last]=child;
if(bac == 0)
{
this.mnuMainMenu.MenuItems.Add(mnuItem[j]);
}
else if(bac == 1)
{
int father =
Convert.ToInt32(child.Attributes["father"].InnerText);
this.mnuMainMenu.MenuItems[father].MenuItems.Add(mnuItem[j]);
}
else if(bac == 2)
{
int grantfather =
Convert.ToInt32(child.Attributes["grantfather"].InnerText);
int father =
Convert.ToInt32(child.Attributes["father"].InnerText);
mnuMainMenu.MenuItems[grantfather].
MenuItems[father].MenuItems.Add(mnuItem[j]);
}
}
}
}
In the above code, I used a Queue
structure so that I can store all MenuItem
s. A Queue
has two main methods: Add
and Get
, Add
method in order to add a new item in the tail of the queue, Get
method in order to get an item from the front of the queue. This rule is called First In First Out (FIFO).
Now, I add node
as the father node of all MenuItem
s into queue
by using the command:
last++;
queue[last]=node;
Now the queue
has only one item node
. Then I begin a loop to find all MenuItem
s. I declare a variable named temp
in order to store a node which is got from the queue
. From that node (temp
), I use another loop to receive all the child nodes of temp
. With each child of temp
, I add it into queue
, and then find the value of the node (example: if value is "File
", it is presented in the menu). I also find the level of this node which is stored in the bac
variable. If bac
equals 0
, this node is the MainItem
of the menu, else if bac
equals 1
, this node is a subitem of the MainItem
of menu, etc. If you want to extend the menu, the menu can have a level 3 or 4; you don't need to modify this code, you just need to continue the code. For example:
if (bac == 3)
{
}
Notes: Besides the code, I have an XML file LanguageMenu.xml that stores all of the details of a menu. The XML file must be located in the same folder as the application (file with extension .exe). Your can continue or modify the file depending on your purpose. The file has a structure, and you must follow that structure. Following the picture below, attribute level
is the level of the current MenuItem
, attribute father
is the position of the father node of the current node.
For example: SubItem value="New File"
has level=1
because it is a child of MainItem ID=e_mnuMain1
, it has father=0
, i.e., the position of its father in MainItem
is 0
.
History
- 8th August, 2005: Last updated
License
This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.
A list of licenses authors might use can be found here.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.