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

相关推荐
咩图23 分钟前
WPF+Prism8.0.0.1909+C#创建一个桌面程序
c#·wpf·prism
雁于飞2 小时前
分布式基础
java·spring boot·分布式·spring·wpf·cloud native
oioihoii7 小时前
WPF入门指南:解析默认项目结构
wpf
极客智造10 小时前
深入解析 ReactiveUI:WPF 响应式 MVVM 开发的 “终极方案”
wpf
Macbethad2 天前
使用WPF编写一个多维度伺服系统的程序
大数据·hadoop·wpf
lingxiao168882 天前
WPF Prism框架应用
c#·wpf·prism
Macbethad3 天前
使用WPF编写一个Ethercat主站的程序
wpf
难搞靓仔3 天前
WPF 弹出窗体Popup
wpf·popup
Macbethad3 天前
使用WPF编写一个MODBUSTCP通信的程序
wpf
unicrom_深圳市由你创科技3 天前
Avalonia.WPF 跨平台图表的使用
wpf