WPF 程序用户权限模块利用MarkupExtension实现控制控件显示

工作记录


MarkupExtension:XAML标记扩展

实现了什么作用:通过扩展标记将一种输入转化为另一种类型的输出

思路:

不直接设置控件的Visibility属性,利用一个标记扩展,传入一个权限值,然后拿这个权限值跟当前程序的用户权限对比,如果控件的权限值高于当前用户权限(比如控件的权限值是管理员,但是当前用户是普通用户),则返回Visibility.Collapsed,反之返回Visibility.Visible。

代码:

cs 复制代码
[MarkupExtensionReturnType(typeof(Visibility))]
public class PermissionVisibleExtension : MarkupExtension, IPermissionListener
{
    private FrameworkElement targetObject;
    private DependencyProperty targetProperty;

    [ConstructorArgument("authority")]
    public Authority Authority { get; set; }

    public PermissionVisibleExtension()
    {

    }

    public PermissionVisibleExtension(Authority authority)
    {
        Authority = authority;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        try
        {
            var providerValuetarget = (IProvideValueTarget)serviceProvider
                .GetService(typeof(IProvideValueTarget));

            //控件对象
            targetObject = (FrameworkElement)providerValuetarget.TargetObject;
            //元素布局事件
            targetObject.Loaded += TargetObject_Loaded;
            //元素删除事件
            targetObject.Unloaded += TargetObject_Unloaded;
            //标记的控件属性
            targetProperty = (DependencyProperty)providerValuetarget.TargetProperty;
            PermissionService.AddListener(this);

            return PermissionService.Authority >= Authority ? Visibility.Visible : Visibility.Collapsed;
        }
        catch (Exception)
        {
            return Visibility.Collapsed;
        }
    }

    private void TargetObject_Loaded(object sender, RoutedEventArgs e)
    {
        PermissionService.AddListener(this);
        PermissionChanged(PermissionService.Authority);
    }

    private void TargetObject_Unloaded(object sender, RoutedEventArgs e)
    {
        PermissionService.RemoveListener(this);
    }

    public void PermissionChanged(Authority authority)
    {
        targetObject.SetCurrentValue(targetProperty, PermissionService.Authority >= Authority ? Visibility.Visible : Visibility.Collapsed);
    }
}

其中IPermissionListener是提供了权限变更处理方法的接口:

cs 复制代码
public interface IPermissionListener
{
    void PermissionChanged(Authority authority);
}

PermissionService是程序的权限管理类,保存着相关控件的扩展标记,提供了挂载方法:

cs 复制代码
private static readonly List<IPermissionListener> listeners = new List<IPermissionListener>();
public static void AddListener(IPermissionListener listener)
{
    if (!listeners.Contains(listener))
    {
        listeners.Add(listener);
    }
}

public static void RemoveListener(IPermissionListener listener)
{
    if (listeners.Contains(listener))
    {
        listeners.Remove(listener);
    }
}

当PermissionService类中的用户权限改变时,会遍历listeners 中的扩展,触发PermissionChanged方法:

cs 复制代码
 private static void OnPermissionChanged()
 {
     foreach (var it in listeners)
     {
         //authority是当前类中的属性,表示用户权限
         it.PermissionChanged(authority);
     }
 }

每个扩展中的PermissionChanged方法:

cs 复制代码
public void PermissionChanged(Authority authority)
{
    targetObject.SetCurrentValue(targetProperty, PermissionService.Authority >= Authority ? Visibility.Visible : Visibility.Collapsed);
}

通过控件直接设置属性值实现改变控件可见状态;

前端写法:

XML 复制代码
 Visibility="{view:PermissionVisible Authority=Expert}">

引用:笔记:WPF中MarkupExtension使用的IServiceProvider参数都有哪些_wpf iserviceprovider-CSDN博客

WPF基础之Binding解析_calcbinding-CSDN博客

相关推荐
dalong1010 小时前
WPF:Modbus 状态监控
wpf·modbus
He BianGu1 天前
【WPF-VisionMaster】机器视觉通用平台V5.0版本发行说明
opencv·c#·wpf·halcon·机器视觉·visionmaster
fogota4 天前
Emoji与Segoe MDL2 Assets的比较
c#·wpf
fogota4 天前
C# WPF 按钮加载字体图标 / 动物头像
c#·.net·wpf
fogota4 天前
C# WPF 按钮加载系统图标 / 动物头像
c#·.net·wpf
军训猫猫头5 天前
C# 封装 MySQL 自动写入与查询工具类(基于 MySqlConnector)
mysql·c#·.net·wpf
gis开发之家6 天前
Spring Boot 4 定时任务与异步线程池:从 @Scheduled 到高并发任务编排(生产级实战)
java·spring boot·后端·wpf·spring boot4
clz13145216 天前
如何设计一个优雅可靠的金融级联机接口
wpf
闲云自留地7 天前
云平台存储管理员:Cinder 创建挂载卷 + Swift 分布式存储原理
分布式·wpf·swift
敲代码的嘎仔8 天前
从集群锁失效到异步领券:我用分布式锁 + Redisson + MQ 把领券接口 RT 从 200ms 压到 15ms
java·数据库·redis·分布式·缓存·ai·wpf