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

五、    

 

版权说明

  如果标题未标有<转载、转>等字则属于作者原创,欢迎转载,其版权归作者和博客园共有。 
  作      者:温景良
  文章出处:http://wenjl520.cnblogs.com/  或  http://www.cnblogs.com/

posted @  2008-12-10 22:22  温景良(Jason) Views( 2345) Comments( 4Edit  收藏

  
#1楼   2008-12-19 02:32 |  龙儿   
高手呀,可是希望能有份源码调试一下,能发份吗,Hong.Lin@163.com 谢谢

  
#2楼   2009-07-22 16:17 |  胡秉征   
大侠,源码发给我一份好吗,hubingzheng@gmail.com,谢谢啦!

  
#3楼   2013-05-17 15:47 |  di40187   
楼主发一份源码给我吧,最近在学winform权限设置,没有头绪,看你这个好像很不错的样子,谢谢啦!987619310@qq.com

  
#4楼   2014-04-16 09:42 |  罗罗づ   
楼主能给份源码吗? 谢谢。。。 1106703231@qq.com


相关文章
|
8月前
38【WinForm】WinForm常见窗体技术汇总
- 窗体调用外部程序与渐变窗体 - 按回车键跳转窗体中的光标焦点 - 剪切板操作
51 0
|
9月前
机房收费系统-登录窗体
机房收费系统-登录窗体
第一次 机房收费系统——登录窗体
第一次 机房收费系统——登录窗体
105 0
第一次 机房收费系统——登录窗体
|
API Windows 容器
WinForm——窗体总结
WinForm——窗体总结
201 0
WinForm——窗体总结
|
机器学习/深度学习 数据可视化 程序员
WinForm控件属性大全
WinForm控件属性大全
400 0
|
供应链 数据可视化 UED