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

相关推荐
Monkey-旭18 小时前
鸿蒙 5.1 深度解析:ArkUI 4.1 升级与分布式开发新范式
分布式·wpf·harmonyos·arkts·openharmony·arkui
FuckPatience3 天前
WPF TabControl页面绑定ItemsSource
wpf
cplmlm3 天前
WPF+MVVM入门学习
c#·wpf
诸葛务农5 天前
人形机器人——电子皮肤技术路线:光学式电子皮肤及MIT基于光导纤维的分布式触觉传感电子皮肤
分布式·机器人·wpf
界面开发小八哥5 天前
界面控件DevExpress WPF中文教程:Data Grid - 绑定数据
ui·.net·wpf·界面控件·devexpress·ui开发
界面开发小八哥6 天前
图表组件SciChart WPF再升级:v8.9带来油气井图、新交互与可视化增强
信息可视化·wpf·数据可视化·scichart
创可贴治愈心灵7 天前
WPF中UI线程频繁操作造成卡顿的处理
ui·c#·wpf
阿登林7 天前
初步学习WPF-Prism
学习·wpf
△曉風殘月〆8 天前
WPF MVVM进阶系列教程(三、使用依赖注入)
wpf·mvvm