天天看點

WinForm下窗體權限設計我的程式人生

一、   描述

管理者通過控制窗體中的某個控件的Enable和visable來達到應用程式的權限控制

二、   設計思路

(一) 讀取控件

将menustrip菜單選項綁定到treeview中,根據菜單選項的名稱跟窗體名稱相等,去

周遊出窗體中的所有form、tabctrol、button、toolstripbutton、等,

結果如下

(二) 儲存控件

将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窗體并傳入菜單中的菜單顯示值做為判斷條件,如果傳入的值可以找到相應窗體,則調用方法周遊此窗體中的所控件

        /// //擷取目前應用程式所有的form窗體并傳入菜單中的菜單顯示值做為判斷條件,如果傳入的值可以找到相應窗體,則調用方法周遊此窗體中的所控件

        /// <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,如果是将基顯示到樹上,

        /// 遞歸周遊一個Form中的控件是否為button,或者是toopstrip中的toolstripbutton,如果是将基顯示到樹上,

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

        /// <param name="treenode">一個treeview的結點</param>

        private void TraverseFormCtrlAndBindTree(Control ctrl, TreeNode treenode)

下面是調用方法将其存入資料庫

5)   TraverseTreeAndRead(TreeNodeCollection treenode)

        #region//此方法周遊樹并切将其内容寫到sql語句裡

        /// 此方法周遊樹并切将其内容寫到sql語句裡

        /// <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();

                        break;

1)      控件應用到窗體

這裡的思路是設定當個窗體内的控件,這裡應用程式所有的窗體都要繼承一個父窗體,在父窗體中寫方法ReturnCtrlInfo(Control ctrl)、SetButtonEnable(Control ctrl, string[,] StrArr)

最後都在load事件中調用如下    ReturnCtrlInfo(this);

對于包含菜單的頁面,這另外在寫個方法.

具體方法如下:

1)   ReturnCtrlInfo(Control ctrl)

        #region//此方法是從資料庫中讀取控件名,後調用方法進行窗體控件初始化

        /// 此方法是從資料庫中讀取控件名,後調用方法進行窗體控件初始化

        /// <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);

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

#region//周遊控件類型,并與資料庫取出的資料比較,後控件控件的可用性

        /////周遊控件類型,并與資料庫取出的資料比較,後控件控件的可用性

        /// <param name="StrArr">在這裡代表資料庫中取出的控件名稱</param>

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

                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:

                                        }

                                    }

                SetButtonEnable(c, StrArr);

五、    

版權說明

  如果标題未标有<轉載、轉>等字則屬于作者原創,歡迎轉載,其版權歸作者和部落格園共有。 

  作      者:溫景良

WinForm下窗體權限設計我的程式人生
WinForm下窗體權限設計我的程式人生

<a href="http://home.cnblogs.com/u/wenjl520/">溫景良(Jason)</a>

<a href="http://home.cnblogs.com/u/wenjl520/followees">關注 - 32</a>

<a href="http://home.cnblogs.com/u/wenjl520/followers">粉絲 - 161</a>

<a>+加關注</a>

1

<a></a>

Post Comment

高手呀,可是希望能有份源碼調試一下,能發份嗎,[email protected] 謝謝

大俠,源碼發給我一份好嗎,[email protected],謝謝啦!

樓主發一份源碼給我吧,最近在學winform權限設定,沒有頭緒,看你這個好像很不錯的樣子,謝謝啦![email protected]

樓主能給份源碼嗎? 謝謝。。。 [email protected]

<b>最新IT新聞</b>:

<b>最新知識庫文章</b>:

本文轉自

部落格園部落格,原文連結:http://www.cnblogs.com/wenjl520/archive/2008/12/10/1352322.html,如需轉載請自行聯系原作者