WinForm下窗体权限设计

简介:

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/

分类: WinForm
0
1
« 上一篇: 备份与恢复数据库的存储过程
» 下一篇: Spreadsheet 对象
posted @ 2008-12-10 22:22 温景良(Jason) Views( 2343) Comments( 4) Edit 收藏

  
#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

相关文章
|
4月前
|
开发框架 前端开发 JavaScript
在Winform界面中使用自定义控件,丰富界面的效果处理
在Winform界面中使用自定义控件,丰富界面的效果处理
|
Shell C++ C语言
38【WinForm】WinForm常见窗体技术汇总
- 窗体调用外部程序与渐变窗体 - 按回车键跳转窗体中的光标焦点 - 剪切板操作
81 0
|
C# 数据安全/隐私保护 Windows
C#编写WinForm 窗体应用程序(第二期)
消息框在 Windows 操作系统经常用到,例如在将某个文件或文件夹移动到回收站中时系统会自动弹出如下图所示的消息框。
C#编写WinForm 窗体应用程序(第二期)
C#编写WinForm窗体应用程序(第四期)
在 C# 语言中 RadioButton 是单选按钮控件,多个 RadioButton 控件可以为一组,这一组内的 RadioButton 控件只能有一个被选中。
C#编写WinForm窗体应用程序(第四期)
C#编写WinForm窗体应用程序(第五期)
列表框 (ListBox) 将所提供的内容以列表的形式显示出来,并可以选择其中的一项或多项内容,从形式上比使用复选框更好一些。
C#编写WinForm窗体应用程序(第五期)
|
C# 数据安全/隐私保护
C# 编写 WinForm 窗体应用程序(第三期)
文本框 (TextBox) 是在窗体中输入信息时最常用的控件,通过设置文本框属性可以实现多行文本框、密码框等。
C# 编写 WinForm 窗体应用程序(第三期)
|
API Windows 容器
WinForm——窗体总结
WinForm——窗体总结
248 0
WinForm——窗体总结
|
机器学习/深度学习 数据可视化 程序员
WinForm控件属性大全
WinForm控件属性大全
442 0
|
C# Windows 安全
WinForm控件与WPF控件的交互
原文:WinForm控件与WPF控件的交互 这个问题其实也可以理解为:怎样在WPF/XAML中使用Winform中的控件(如PictureBox)?首先看看XAML代码:(注意下面加粗的部分)              ...
1087 0
|
C# Windows
使用WPF技术模拟手机界面
原文:使用WPF技术模拟手机界面 1. 前言 WPF(Windows Presentation Foundation),即“Windows呈现基础”,它的目的非常明确,就是用来把数据“显示”给用户看的(说白了就是用来做UI的)。
1680 0