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博客

相关推荐
Wang's Blog9 小时前
AI Agent白手起家60: 多智能体架构解析与 LangGraph 入门
人工智能·架构·wpf
.Peter12 小时前
.NET/WPF 程序在部分 Windows 电脑无法保存用户环境变量:使用 DPAPI 实现安全兼容
windows·信息安全·c#·.net·wpf·环境变量·dpapi
dalong102 天前
WPF:3D型材模型
3d·wpf
一念春风2 天前
文件透明加密(C、C#)
c语言·c#·wpf
yanaiding3 天前
C# WPF 独立开发看图工具 PixSight 经验介绍(二)—— 水印模块开发实录
图像处理·c#·wpf·个人开发
我是苏苏5 天前
WPF开发01:基础控件及常用模板篇
开发语言·c#·html·wpf
dalong106 天前
WPF:3D顶点共享与法线设置对光照效果的影响
3d·wpf
柔蘭7 天前
WPF中的CommunityToolkit.Mvvm框架
wpf
aGdF8E3gQ7 天前
【Application Insights】采样率对Function App日志收集的影响和解决方法
python·flask·wpf
程序员-Benothing8 天前
如何实现高并发系统订单30分钟自动关闭?
开发语言·c#·wpf