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

相关推荐
张人玉4 小时前
C#WPF UI路由事件:事件冒泡与隧道机制
ui·c#·wpf
Aevget7 小时前
DevExpress WPF v25.2新功能预览 - 支持将JetBrains Rider与报表设计器集成
.net·wpf·界面控件·devexpress·ui开发
Aevget13 小时前
界面控件DevExpress WPF v25.1新版亮点:AI功能的全面升级
c#·.net·wpf·界面控件·devexpress·ui开发
beyond谚语2 天前
第一章 WPF概述
wpf
necessary6532 天前
从工行“余额归零”事件看CAP定理:当金融系统在一致性与可用性之间做出选择
分布式·金融·wpf·可用性测试
棉晗榜3 天前
WPF隐藏控件后,怎么让其上部的控件空间自动撑高
wpf
壹佰大多3 天前
【Redisson分布式锁源码分析-3】
数据结构·分布式·mysql·spring·spring cloud·wpf·lua
LateFrames4 天前
以小白视角尝试 WPF / WinUI3 / MAUI / MAUI Blazor 构建 Windows 桌面程序
windows·wpf·maui·mauiblazor·winui3
偶尔的鼠标人4 天前
Avalonia/WPF 打开子窗口,并且跨页面传值
c#·wpf·mvvm·avalonia
玖笙&4 天前
✨WPF编程进阶【6.1】:图形原则(附源码)
c++·c#·wpf·visual studio