WPF 程序用户权限模块利用MarkupExtension实现控制控件显示
工作记录
-------------------------------------------------------------------------------------------------------
MarkupExtension:XAML标记扩展
实现了什么作用:通过扩展标记将一种输入转化为另一种类型的输出
思路:
不直接设置控件的Visibility属性,利用一个标记扩展,传入一个权限值,然后拿这个权限值跟当前程序的用户权限对比,如果控件的权限值高于当前用户权限(比如控件的权限值是管理员,但是当前用户是普通用户),则返回Visibility.Collapsed,反之返回Visibility.Visible。
代码:
[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是提供了权限变更处理方法的接口:
public interface IPermissionListener
{void PermissionChanged(Authority authority);
}
PermissionService是程序的权限管理类,保存着相关控件的扩展标记,提供了挂载方法:
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方法:
private static void OnPermissionChanged(){foreach (var it in listeners){//authority是当前类中的属性,表示用户权限it.PermissionChanged(authority);}}
每个扩展中的PermissionChanged方法:
public void PermissionChanged(Authority authority)
{targetObject.SetCurrentValue(targetProperty, PermissionService.Authority >= Authority ? Visibility.Visible : Visibility.Collapsed);
}
通过控件直接设置属性值实现改变控件可见状态;
前端写法:
Visibility="{view:PermissionVisible Authority=Expert}">
引用:笔记:WPF中MarkupExtension使用的IServiceProvider参数都有哪些_wpf iserviceprovider-CSDN博客
WPF基础之Binding解析_calcbinding-CSDN博客