工作記錄
-------------------------------------------------------------------------------------------------------
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博客