c#WinForm下窗体权限设计(遍历菜单下的所有菜单及所有form、form中的控件)

c#WinForm下窗体权限设计(遍历菜单下的所有菜单及所有form、form中的控件)

WinForm下窗体权限设计

 

一、   描述

管理员通过控制窗体中的某个控件的Enablevisable来达到应用程序的权限控制

二、   设计思路

(一) 读取控件

menustrip菜单选项绑定到treeview中,根据菜单选项的名称跟窗体名称相等,去

遍历出窗体中的所有formtabctrolbuttontoolstripbutton、等,

结果如下

(二) 保存控件

treeview中显示 的控件id跟控件名称一起存入数据库,同时设置控件的可用状态,默认都可用。

(三) 将权限应用到具体窗体中


 

 

三、   数据库的设计

四、   关键部位的实现

1)      读取控件的难点

怎么样遍历到应用程序的所有窗体,这里使用了net的反射()

具体方法如下

1)         TraverseForm(string Str)

        public bool TraverseForm(string Str)

        {

            Assembly a = Assembly.LoadFile(Application.ExecutablePath);//.net中的反射

 

            Type[] types = a.GetTypes();

            foreach (Type t in types)

            {

 

                if (t.BaseType.Name == "Form" || t.BaseType.Name == "F_HKXT")

                {

                    Form f = (Form)Activator.CreateInstance(t, true);

 

                    if (f != null)

                    {

                        // MessageBox.Show(f.Text);

                        if (f.Text == Str)

                        {

 

                            return true;

                        }

 

                    }

                }

 

 

            }

            return false;

        }

 

上面这个方法是进行判断窗体的存在性,下面这个方法是将窗体显示到树中

2)   TraverseMenu(Control ctrl)

        #region//遍历MenuStrip所有子菜单并显示到树上,同时判断每个子菜单下是否有子窗体,是调用TraverseFormBDTree方法将其窗体及其控件名显示到treeview

        /// <summary>

        /// 遍历MenuStrip所有子菜单并显示到树上,同时判断每个子菜单下是否有子窗体,是调用TraverseFormBDTree方法将其窗体及其控件名显示到treeview

        /// </summary>

        /// <param name="ctrl">是带有Menustrip的一个Form窗体</param>

        public void TraverseMenu(Control ctrl)

        {

            foreach (Control c in ctrl.Controls)//遍历窗体中的控件

            {

                //toolbar1(c);

                if (c is MenuStrip)//判断控件是否为Menustrip

                {

 

 

                    MenuStrip menu = (MenuStrip)c;

 

                    foreach (ToolStripMenuItem MenuItem2 in menu.Items)//遍历menustrip的一级菜单并将其显示到树上

                    {

 

                        treeView1.Nodes.Add(MenuItem2.Name, MenuItem2.Text);

                        treeView1.Nodes[MenuItem2.Name].ToolTipText = "主菜单";

 

                        if (TraverseForm(MenuItem2.Text.Trim()) == true)//调用方法TraverseForm判断是否存在窗体

                        {

                            TraverseFormBDTree(MenuItem2.Text, treeView1.Nodes[MenuItem2.Name]);//存在调用方法TraverseFormBDTree

 

                        }

                        else

                        {

                            for (int i = 0; i < MenuItem2.DropDownItems.Count; i++)//遍历menustrip遍历二级菜单

                            {

                                treeView1.Nodes[MenuItem2.Name].Nodes.Add(MenuItem2.DropDownItems[i].Name, MenuItem2.DropDownItems[i].Text);

                                treeView1.Nodes[MenuItem2.Name].Nodes[MenuItem2.DropDownItems[i].Name].ToolTipText = "一级子菜单";

                                if (TraverseForm(MenuItem2.DropDownItems[i].Text) == true)

                                {

                                    TraverseFormBDTree(MenuItem2.DropDownItems[i].Text, treeView1.Nodes[MenuItem2.Name].Nodes[MenuItem2.DropDownItems[i].Name]);

                                }

                            }

                        }

 

                    }

 

 

                }

 

            }

        }

 

        #endregion

 

上面方法调用了下面这个方法

3)   TraverseFormBDTree(string Str, TreeNode treenode)

 

     #region//获取当前应用程序所有的form窗体并传入菜单中的菜单显示值做为判断条件,如果传入的值可以找到相应窗体,则调用方法遍历此窗体中的所控件

        /// <summary>

        /// //获取当前应用程序所有的form窗体并传入菜单中的菜单显示值做为判断条件,如果传入的值可以找到相应窗体,则调用方法遍历此窗体中的所控件

        /// </summary>

        /// <param name="Str">这里为菜单菜单的显示值</param>

        /// <param name="treenode">树的节点</param>

        public void TraverseFormBDTree(string Str, TreeNode treenode)

使用这个方法后会继续调用 方法  private void TraverseFormCtrlAndBindTree(Control ctrl, TreeNode treenode)将控件名与id也绑定到树中

 

4)   private void TraverseFormCtrlAndBindTree(Control ctrl, TreeNode treenode)

 

 

   #region//递归遍历一个Form中的控件是否为button,或者是toopstrip中的toolstripbutton,如果是将基显示到树上,

        /// <summary>

        /// 递归遍历一个Form中的控件是否为button,或者是toopstrip中的toolstripbutton,如果是将基显示到树上,

        /// </summary>

        /// <param name="ctrl">窗体的控件</param>

        /// <param name="treenode">一个treeview的结点</param>

        private void TraverseFormCtrlAndBindTree(Control ctrl, TreeNode treenode)

 

下面是调用方法将其存入数据库

5)   TraverseTreeAndRead(TreeNodeCollection treenode)

 

        #region//此方法遍历树并切将其内容写到sql语句里

        /// <summary>

        /// 此方法遍历树并切将其内容写到sql语句里

        /// </summary>

        /// <param name="treenode">传入的一组TreeNodeCollection类型的树节点</param>

        private void TraverseTreeAndRead(TreeNodeCollection treenode)

        {

 

            foreach (TreeNode TN in treenode)//遍历窗体中的控件

            {

                switch (TN.ToolTipText)

                {

                    case "主菜单":

                        Code.SetControl.P_Str_MainMenuText = "主菜单" + "^" + TN.Text;

                        Code.SetControl.P_Str_Sub1MenuText = "Sub1Menu";

                        Code.SetControl.P_Str_Sub2MenuText = "Sub2Menu";

                        Code.SetControl.P_Str_Sub3MenuText = "Sub3Menu";

                        Code.SetControl.P_Str_Sub4MenuText = "Sub4Menu";

                        Code.SetControl.P_Str_Sub5MenuText = "Sub5Menu";

                        Code.SetControl.P_Str_BtnText = "P_Str_BtnText";

                        Code.SetControl.P_Str_TSBtnText = "P_Str_TSBtnText";

                        Code.SetControl.P_Str_TP1Text = "P_Str_TP1Text";

                        Code.SetControl.P_Str_TP2Text = "P_Str_TP2Text";

                        Code.SetControl.P_Str_TP1PageText = "P_Str_TP1PageText";

                        Code.SetControl.P_Str_TP2PageText = "P_Str_TP2PageText ";

 

                        sqlStr = "insert into d_privi_lib  (login_code,app_name,main_menu,sub1_menu,sub2_menu,sub3_menu,sub4_menu,window_name,tab_name,tabpage_name,tab_name2,tabpage_name2,click_name,use_flag,p_order) " +

                               "values('" + Code.InitData.UserLogin.USER_CODE + "','" + Code.SetControl.P_Str_AppName + "','" + Code.SetControl.P_Str_MainMenuText + "','" + Code.SetControl.P_Str_Sub1MenuText + "','" + Code.SetControl.P_Str_Sub2MenuText + "','" + Code.SetControl.P_Str_Sub3MenuText + "','" + Code.SetControl.P_Str_Sub4MenuText + "','c_hkxt','" + Code.SetControl.P_Str_TP1Text + "','" + Code.SetControl.P_Str_TP1PageText + "','" + Code.SetControl.P_Str_TP2Text + "','" + Code.SetControl.P_Str_TSBtnText + "','" + Code.SetControl.P_Str_BtnText + "','T','123456')";

                        sqlStrArr[i] = EStr.EncryptString(sqlStr, Code.InitData.DESKey);

                        i++;

                        TraverseTreeAndRead(TN.Nodes);

                    default:

                        Code.SetControl.P_Str_TSBtnText = "怎么会多出这个呀!" + i.ToString();

                        sqlStr = "insert into d_privi_lib  (login_code,app_name,main_menu,sub1_menu,sub2_menu,sub3_menu,sub4_menu,window_name,tab_name,tabpage_name,tab_name2,tabpage_name2,click_name,use_flag,p_order) " +

                               "values('" + Code.InitData.UserLogin.USER_CODE + "','" + Code.SetControl.P_Str_AppName + "','" + Code.SetControl.P_Str_MainMenuText + "','" + Code.SetControl.P_Str_Sub1MenuText + "','" + Code.SetControl.P_Str_Sub2MenuText + "','" + Code.SetControl.P_Str_Sub3MenuText + "','" + Code.SetControl.P_Str_Sub4MenuText + "','c_hkxt','" + Code.SetControl.P_Str_TP1Text + "','" + Code.SetControl.P_Str_TP1PageText + "','" + Code.SetControl.P_Str_TP2Text + "','" + Code.SetControl.P_Str_TSBtnText + "','" + Code.SetControl.P_Str_BtnText + "','T','123456')";

                        sqlStrArr[i] = EStr.EncryptString(sqlStr, Code.InitData.DESKey);

                        i++;

                        TraverseTreeAndRead(TN.Nodes);

                        break;

 

                }

 

 

 

            }

 

        }

 

        #endregion

1)      控件应用到窗体

这里的思路是设置当个窗体内的控件,这里应用程序所有的窗体都要继承一个父窗体,在父窗体中写方法ReturnCtrlInfo(Control ctrl)SetButtonEnable(Control ctrl, string[,] StrArr)

最后都在load事件中调用如下    ReturnCtrlInfo(this);

对于包含菜单的页面,这另外在写个方法.

具体方法如下:

1)   ReturnCtrlInfo(Control ctrl)

 

        #region//此方法是从数据库中读取控件名,后调用方法进行窗体控件初始化

        /// <summary>

        /// 此方法是从数据库中读取控件名,后调用方法进行窗体控件初始化

        /// </summary>

        /// <param name="ctrl">控件的名称</param>

 

        public void ReturnCtrlInfo(Control ctrl)

        {

            DataTable DT = new DataTable();

            sqlStr = "select * from d_privi_lib where login_code='liruiba'";

            DS = cser.ReturnDS1(EStr.EncryptString(sqlStr, Code.InitData.DESKey));

            // DS.Tables[0].DefaultView.RowFilter = "SUB1_MENU='toolStripMenuItem4^控件权限设置'";

            DS.Tables[0].DefaultView.RowFilter = "SUB1_MENU ='一级子菜单^" + ctrl.Text + "'";

            DT = DS.Tables[0].DefaultView.ToTable();

            string[,] StrArr = new string[DS.Tables[0].Rows.Count, 2];

            for (int i = 0; i < DT.Rows.Count; i++)

            {

                StrArr[i, 0] = DT.Rows[i]["click_name"].ToString().Split('^').GetValue(0).ToString();//控件名称

                StrArr[i, 1] = DT.Rows[i]["Use_Flag"].ToString();//控件可用标志

                //MessageBox.Show(StrArr[i].ToString());

                // MessageBox.Show(StrArr[i, 0].ToString() + StrArr[i, 1].ToString());

            }

            SetButtonEnable(ctrl, StrArr);

        }

        #endregion

 

 

2)   SetButtonEnable(Control ctrl, string[,] StrArr)

 

#region//遍历控件类型,并与数据库取出的数据比较,后控件控件的可用性

        /// <summary>

        /遍历控件类型,并与数据库取出的数据比较,后控件控件的可用性

        /// </summary>

        /// <param name="ctrl">控件的名称</param>

        /// <param name="StrArr">在这里代表数据库中取出的控件名称</param>

        void SetButtonEnable(Control ctrl, string[,] StrArr)

        {

            foreach (Control c in ctrl.Controls)//遍历窗体中的控件

            {

            

                if (c is ToolStrip) //判断是否为ToolStrip

                {

                    ToolStrip TB = (ToolStrip)c;

 

                    for (int i = 0; i < TB.Items.Count; i++)

                    {

 

                        //MessageBox.Show(TB.Items[i].GetType().ToString());

                        if (TB.Items[i].GetType().ToString() == "System.Windows.Forms.ToolStripButton")//判断是否为ToolStripButton

                        {

                            for (int j = 0; j < StrArr.GetLength(0); j++)

                            {

                                if (StrArr[j, 0] != null)

                                {

                                    // MessageBox.Show(StrArr[i, 0].ToString() + StrArr[i, 1].ToString());

                                    if (TB.Items[i].Name == StrArr[j, 0].ToString())

                                    {

                                        switch (StrArr[j, 1].ToString())

                                        {

 

                                            case "T":

 

                                                ((ToolStripButton)TB.Items[i]).Enabled = true;

                                                break;

                                            case "F":

                                                ((ToolStripButton)TB.Items[i]).Enabled = false;

                                                break;

                                            default:

                                                break;

 

                                        }

                                    }

                                }

 

                            }

                        }

                    }

                }

 

 

                SetButtonEnable(c, StrArr);

            }

        }

        #endregion

五、    

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值