根据角色决定是否显示或者启用控件

本文介绍了一种根据用户角色动态控制控件显示与启用状态的方法。通过自定义组件扩展了控件的功能,实现了根据角色自动调整控件的可见性和可用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

该篇文章是我于2009年6月10日通过自己编写的工具,批量从位于在博客园的博客站点(http://chenxizhang.cnblogs.com)同步而来。文章中的图片地址仍然是链接到博客园的。特此说明!

陈希章

原文地址:http://www.cnblogs.com/chenxizhang/archive/2008/08/17/1269661.html
原文标题:根据角色决定是否显示或者启用控件
原文发表:2008/8/17 2:43:00

让我们一起来想一下这么一个场景:我们的程序中有很多控件,他们需要根据当前用户的角色不同去决定是否要显示,或者是否启用?你会怎么做这个事情呢?

很多朋友说,这还不简单吗?我在窗体加载的时候去检查就可以了。这个思路是行得通的,但在实现上有几个问题

1. 在什么地方存储这些角色设置呢

2. 每个控件都要去验证,会不会出现大量重复的代码

我的解决方案是参照Tooltip那种组件的做法来实现。想想看,假如我们要为大量控件设置tooltip,那么我们会用该组件,而如果一个窗体上有一个Tooltip组件之后,那么其他的控件的属性中就会多出来一个特殊的属性,如下图所示

image

也就是说,Tooltip给原有控件进行了一个扩展。这的确很神奇。如果我们在这里设置了内容,我们来看看在后台代码中发生了什么事情

image

这就是它的工作原理,我们来总结一下

1. Tooltip是一个组件,它"神奇"地扩展了现有控件的属性

2. 实际上该属性的设置是通过一个SetTooltip的方法来做的。【而不能用标准的属性指派的方式去做】

了解了以上原理之后,我们回到自己的需求:我们需要让每个控件能随着用户的角色不同而决定是否显示,或者启用。这难道与Tooltip的机制不是很相似么?好吧,我们开始干吧

using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

using System.Threading;

namespace Xizhang.Security.Windows

{
    ///


    /// 该类型扩展了控件的安全设置,可以根据角色来决定是否显示或者启用
    /// 作者:陈希章
    ///

    [ProvideProperty("SecureVisible",typeof(Control))]//这里公开两个属性,其实也不能说是属性,因为该类型里面并不需要该属性。总之它跟上面的Tooltip很类似。
    [ProvideProperty("SecureEnable",typeof(Control))]
    public partial class SecurityContext : Component,IExtenderProvider //必须实现IExtenderProvider接口
    {
        Dictionary VisiblerolesList = new Dictionary ();
        Dictionary EnablerolesList = new Dictionary ();

        public SecurityContext()
        {
            InitializeComponent();
        }

        public SecurityContext(IContainer container)
        {
            container.Add(this);
            InitializeComponent();
        }

        #region IExtenderProvider 成员

        public bool CanExtend(object extendee)//这是接口唯一要实现的方法,决定对那些控件进行扩展,这将决定在哪些控件的属性窗格中看到它
        {
            if (extendee is Control && !(extendee is Form))//我们这里指定必须是控件,但不能是窗体
            {
                return true;
            }
            return false;
        }

        public void SetSecureVisible(Control ctrl, string role) //注意这个和下面那个方法。既然我们公开了属性名叫SecureVisible,那么我们就必须实现两个相应的方法,一个是Set,一个是Get
        {
            if (!VisiblerolesList.ContainsKey(ctrl))
            {
                if (!string.IsNullOrEmpty(role))
                {
                    ctrl.Visible = Thread.CurrentPrincipal.IsInRole(role);
                }
                VisiblerolesList.Add(ctrl, role);
            }
            else
                VisiblerolesList[ctrl] = role;
        }

        public string GetSecureVisible(Control ctrl)
        {
            if (VisiblerolesList.ContainsKey(ctrl))
                return VisiblerolesList[ctrl];
            else
                return string.Empty;
        }

        public void SetSecureEnable(Control ctrl, string role)
        {
            if (!EnablerolesList.ContainsKey(ctrl))
            {
                if (!string.IsNullOrEmpty(role))
                {
                    ctrl.Enabled = Thread.CurrentPrincipal.IsInRole(role);
                }
                EnablerolesList.Add(ctrl, role);
            }
            else
                EnablerolesList[ctrl] = role;
        }

        public string GetSecureEnable(Control ctrl)
        {
            if (EnablerolesList.ContainsKey(ctrl))
                return EnablerolesList[ctrl];
            else
                return string.Empty;
        }
        #endregion
    }
}

2. 在窗体上使用它,我们看到是和Tooltip类似的效果

image

3. 激动人心的时刻到了,我们现在在登录的时候指派角色

MyIdentity identity = new MyIdentity("chenxizhang");
MyPrinciple principle = new MyPrinciple(identity, new string[] { "Admin" });
Thread.CurrentPrincipal = principle;

注意,这里我用的是自定义标识和主体。关于该主题,你可以参考http://www.cnblogs.com/chenxizhang/archive/2008/08/17/1269658.html

注意观察,我们在SecureEnable中设置为Admin,表示只有Admin角色才能使用该按钮。我们在SecureVisible中设置为空,表示任何人都可以看到该按钮。然后,因为我们在登录的时候指派角色为Admin,所以该用户是既可以看到,又可以使用该按钮的。如下图所示

image

换言之,如果用户不具备Admin角色,那么按钮就会变成灰色

MyIdentity identity = new MyIdentity("chenxizhang");
MyPrinciple principle = new MyPrinciple(identity, new string[] { "PowerUser" });
Thread.CurrentPrincipal = principle;

image
作者:陈希章
出处:http://blog.youkuaiyun.com/chen_xizhang
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值