Introduction
This article tries to explain how to create a Database Driven MenuStrip and add Items to the MenuStrip using the ToolStripMenuItem class in a C# Windows Forms application.
Using the Code
1. Create a new project and give it the name "DynamicMenuStripDBDriven".
2. Rename the "Form1" to "FrmParent", which is the parent window, since we will be dealing with multiple forms.
MenuStrip
The MenuStrip gives an easier approach to represent and group application commands.
To add a MenuStrip Dynamically at run-time we create an instance of the "MenuStrip" Class.
//Creating object of MenuStrip class
MenuStrip MnuStrip = new MenuStrip ();
To add the MenuStrip control to the Form, we use the "Add" property:
this.Controls.Add (MnuStrip);
Here we will be working with Child Forms, so set its "IsMdiContainer" property to true.
// To make the Form as the Parent Form
this.IsMdiContainer = true;
Code
this.IsMdiContainer = true;
MenuStrip MnuStrip = new MenuStrip();
this.Controls.Add(MnuStrip);
After executing the piece of code in the Form load event, our Form looks something like this:
Figure 1: Placing the MenuStrip control in the Form
3. A MenuStrip is nothing without MenuItems. To add MenuItems to the MenuStrip we use the ToolStripMenuItem class.
In this instance we have created Tables since we need to Load the Menu Items Dynamically:
To Load the Main Menu:
CREATE TABLE [dbo].MNU_PARENT(
MAINMNU varchar(20),
STATUS varchar(1),
MENUPARVAL int
)
Sample Insert statement to Load the Parent Menu:
INSERT INTO MNU_PARENT(MAINMNU,STATUS,MENUPARVAL)
VALUES('Transactions','Y',1)
INSERT INTO MNU_PARENT(MAINMNU,STATUS,MENUPARVAL)
VALUES('Inventory','Y',2)
To Load the Sub Menus to the Form:
CREATE TABLE [dbo].[MNU_SUBMENU](
MENUPARVAL int,
FRM_CODE varchar(50) ,
FRM_NAME varchar(20),
STATUS varchar(1)
)
Sample Insert statement to the "MNU_SUBMENU" table to Load Submenus to the Form:
INSERT INTO MNU_SUBMENU(MENUPARVAL,FRM_CODE,FRM_NAME,STATUS)
VALUES(1,'FrmAccount','Accounting','Y')
INSERT INTO MNU_SUBMENU(MENUPARVAL,FRM_CODE,FRM_NAME,STATUS)
VALUES(1,'FrmFinance','Finance','Y')
INSERT INTO MNU_SUBMENU(MENUPARVAL,FRM_CODE,FRM_NAME,STATUS)
VALUES(1,null,'Despatch','Y')
Here, the "MENUPARVAL" value in the "MNU_SUBMENU" table is 1, since this will be the submenu for the "Transactions Menu".
4. To start, add 2 Windows Forms to the Project using Project -> Add Windows Form and rename it and create a structure as shown below:
Figure 2: Structure of the Project
5. The ToolStripMenuItem shows differently depending on whether it is a Top-level Menu Item in
a MenuStrip Control or a sub menu.
When it a Sub-Menu it shows a margin to the left where images are displayed if we have added some.
Menu Items are added to the MenuStrip using the Items Collection and we can also add properties for handling shortcut keys and supporting checked menu items.
In the Form Load event, paste the following code:
private void FrmParent_Load(object sender, EventArgs e)
{
// To make this Form the Parent Form
this.IsMdiContainer = true;
//Creating object of MenuStrip class
MnuStrip = new MenuStrip();
//Placing the control to the Form
this.Controls.Add(MnuStrip);
String connectionString;
connectionString = ConfigurationManager.ConnectionStrings["dbconn"].ConnectionString;
conn = new SqlConnection(connectionString);
String Sequel = "SELECT MAINMNU,MENUPARVAL,STATUS FROM MNU_PARENT";
SqlDataAdapter da = new SqlDataAdapter(Sequel, conn);
DataTable dt = new DataTable();
conn.Open();
da.Fill(dt);
foreach (DataRow dr in dt.Rows)
{
MnuStripItem = new ToolStripMenuItem(dr["MAINMNU"].ToString());
//SubMenu(MnuStripItem, dr["MENUPARVAL"].ToString());
MnuStrip.Items.Add(MnuStripItem);
}
// The Form.MainMenuStrip property determines the merge target.
this.MainMenuStrip = MnuStrip;
}
Figure 3: Loading the Main Menu
In the code above, we read the Settings of the Configuration File and loaded the Parent Menu.
6. Adding Submenus
To add a Sub Menu to the Transactions Menu, we use the "ToolStripMenuItem" Class; I have included this piece of Code to Load the SubMenu.
Method
public void SubMenu(ToolStripMenuItem mnu, string submenu)
{
String Seqchild = "SELECT FRM_NAME FROM MNU_SUBMENU WHERE MENUPARVAL='" + submenu + "'";
SqlDataAdapter dachildmnu = new SqlDataAdapter(Seqchild, conn);
DataTable dtchild = new DataTable();
dachildmnu.Fill(dtchild);
foreach (DataRow dr in dtchild.Rows)
{
ToolStripMenuItem SSMenu = new ToolStripMenuItem(dr["FRM_NAME"].ToString(), null, new EventHandler(ChildClick));
mnu.DropDownItems.Add(SSMenu);
}
}
The piece of code above loads the SubMenus for each Parent. Here we loop each form and register the events with the ChildClick.
7. Child Click Event
private void ChildClick(object sender, EventArgs e)
{
// MessageBox.Show(string.Concat("You have Clicked ", sender.ToString(), " Menu"), "Menu Items Event",MessageBoxButtons.OK, MessageBoxIcon.Information);
String Seqtx = "SELECT FRM_CODE FROM MNU_SUBMENU WHERE FRM_NAME='" + sender.ToString() + "'";
SqlDataAdapter datransaction = new SqlDataAdapter(Seqtx, conn);
DataTable dtransaction = new DataTable();
datransaction.Fill(dtransaction);
Assembly frmAssembly = Assembly.LoadFile(Application.ExecutablePath);
foreach (Type type in frmAssembly.GetTypes())
{
//MessageBox.Show(type.Name);
if (type.BaseType == typeof(Form))
{
if (type.Name == dtransaction.Rows[0][0].ToString())
{
Form frmShow = (Form)frmAssembly.CreateInstance(type.ToString());
// then we close all of the child Forms with simple below code
foreach (Form form in this.MdiChildren)
{
form.Close();
}
frmShow.MdiParent = this;
frmShow.WindowState = FormWindowState.Maximized;
//frmShow.ControlBox = false;
frmShow.Show();
}
}
}
}
Here,
String Seqtx = "SELECT FRM_CODE FROM MNU_SUBMENU WHERE FRM_NAME='" + sender.ToString() + "'";
To get the "FRM_CODE", in other words the Form name:
Assembly frmAssembly = Assembly.LoadFile(Application.ExecutablePath);
Here we add the namespace System.Reflection to our project that contains classes that allow us to obtain information about the application dynamically at run-time.
The classes that provide access to the metadata of the running program are available in the System.Reflection namespace.
type.BaseType == typeof(Form)
Comparing the BaseType of the application to Form and get the Type from which System.Type is inherited:
type.Name == dtransaction.Rows[0][0].ToString()
Comparing the name of the form with the form that is present in the Database:
Form frmShow = (Form)frmAssembly.CreateInstance(type.ToString());
Creating an instance of the form by Locating the specified type from the Assembly.
Entire code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Configuration;
using System.Reflection;
namespace DynamicMenuStripDBDriven
{
public partial class FrmParent : Form
{
SqlConnection conn;
MenuStrip MnuStrip;
ToolStripMenuItem MnuStripItem;
public FrmParent()
{
InitializeComponent();
}
private void FrmParent_Load(object sender, EventArgs e)
{
// To make this Form the Parent Form
this.IsMdiContainer = true;
//Creating object of MenuStrip class
MnuStrip = new MenuStrip();
//Placing the control to the Form
this.Controls.Add(MnuStrip);
String connectionString;
connectionString = ConfigurationManager.ConnectionStrings["dbconn"].ConnectionString;
conn = new SqlConnection(connectionString);
String Sequel = "SELECT MAINMNU,MENUPARVAL,STATUS FROM MNU_PARENT";
SqlDataAdapter da = new SqlDataAdapter(Sequel, conn);
DataTable dt = new DataTable();
conn.Open();
da.Fill(dt);
foreach (DataRow dr in dt.Rows)
{
MnuStripItem = new ToolStripMenuItem(dr["MAINMNU"].ToString());
SubMenu(MnuStripItem, dr["MENUPARVAL"].ToString());
MnuStrip.Items.Add(MnuStripItem);
}
// The Form.MainMenuStrip property determines the merge target.
this.MainMenuStrip = MnuStrip;
}
public void SubMenu(ToolStripMenuItem mnu, string submenu)
{
String Seqchild = "SELECT FRM_NAME FROM MNU_SUBMENU WHERE MENUPARVAL='" + submenu + "'";
SqlDataAdapter dachildmnu = new SqlDataAdapter(Seqchild, conn);
DataTable dtchild = new DataTable();
dachildmnu.Fill(dtchild);
foreach (DataRow dr in dtchild.Rows)
{
ToolStripMenuItem SSMenu = new ToolStripMenuItem(dr["FRM_NAME"].ToString(), null, new EventHandler(ChildClick));
mnu.DropDownItems.Add(SSMenu);
}
}
private void ChildClick(object sender, EventArgs e)
{
// MessageBox.Show(string.Concat("You have Clicked ", sender.ToString(), " Menu"), "Menu Items Event",MessageBoxButtons.OK, MessageBoxIcon.Information);
String Seqtx = "SELECT FRM_CODE FROM MNU_SUBMENU WHERE FRM_NAME='" + sender.ToString() + "'";
SqlDataAdapter datransaction = new SqlDataAdapter(Seqtx, conn);
DataTable dtransaction = new DataTable();
datransaction.Fill(dtransaction);
Assembly frmAssembly = Assembly.LoadFile(Application.ExecutablePath);
foreach (Type type in frmAssembly.GetTypes())
{
//MessageBox.Show(type.Name);
if (type.BaseType == typeof(Form))
{
if (type.Name == dtransaction.Rows[0][0].ToString())
{
Form frmShow = (Form)frmAssembly.CreateInstance(type.ToString());
// then when you want to close all of them simple call the below code
foreach (Form form in this.MdiChildren)
{
form.Close();
}
frmShow.MdiParent = this;
frmShow.WindowState = FormWindowState.Maximized;
//frmShow.ControlBox = false;
frmShow.Show();
}
}
}
}
}
}
When we run the project:
Clicking the Accounting Form
Clicking the Finance Transaction
Summary
In this article we have discussed how to create a Database Driven MenuStrip in a Windows Form and adding Submenus using the ToolStripMenuItem class and registering the Event for the Child Forms and navigating through the forms in the Project to associate them with the Form Name dynamically in the database.