动态分配 UI 权限 WPF [英] Assign UI Permissions WPF dynamically
问题描述
可能的重复:
在代码隐藏中设置 WPF UI 权限
我开始使用 WPF 并希望创建一个应用程序,该应用程序将根据用户 (AD) 及其角色 (自定义) 显示/隐藏控件.
I am starting to work with WPF and want to create an application that will show/hide controls depending on the user(AD) and his role(s)(Custom).
我设法通过使用继承 MarkupExpension & 的类来实现此目的.IValueConverter.
I managed to get this working by using a class inheriting MarkupExpension & IValueConverter.
public class RoleToVisibilityConverter : MarkupExtension,IValueConverter
{
public RoleToVisibilityConverter()
{
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var principal = value as GenericPrincipal;
bool IsValidUser = false;
if (principal != null)
{
foreach (String role in parameter.ToString().Split(';'))
{
if (principal.IsInRole(role))
{
IsValidUser = true;
break;
}
}
return IsValidUser ? Visibility.Visible : Visibility.Collapsed;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
在 XAML 中,我为可见性添加了以下绑定:
And in the XAML I add the following binding for Visibility:
Visibility="{Binding Source={x:Static systhread:Thread.CurrentPrincipal}, ConverterParameter=admin;editor;readonly, Converter={rv:RoleToVisibilityConverter}}
Visibility="{Binding Source={x:Static systhread:Thread.CurrentPrincipal}, ConverterParameter=admin;editor;readonly, Converter={rv:RoleToVisibilityConverter}}
注意:我还需要将 xmlns:systhread="clr-namespace:System.Threading;assembly=mscorlib" 添加到 MainWindow.xaml.
Note: I also need to add xmlns:systhread="clr-namespace:System.Threading;assembly=mscorlib" to the MainWindow.xaml.
我的问题是:
上面的示例是完成此操作的最佳方式还是(正如我所想的)动态加载可见性绑定.
Is the above example the best way to accomplish this or (as I was thinking) to dynamically load the visibility bindings dynamically.
任何帮助将不胜感激.
诺埃尔.
推荐答案
您可以尝试改用 Behavior.我创建了一些您可以查看的简单代码:
You could try using a Behavior instead. I created some simple code you can look through:
public class Permission
{
private List<string> roles = new List<string>();
public List<string> Roles
{
get { return roles; }
set { roles = value; }
}
}
public class PermissionBehavior
{
// Static behaviour parameters
public static readonly Dictionary<FrameworkElement, PermissionBehavior> Instances = new Dictionary<FrameworkElement, PermissionBehavior>();
public static readonly DependencyProperty PermissionProperty =
DependencyProperty.RegisterAttached("Permission", typeof(Permission), typeof(PermissionBehavior),
new PropertyMetadata(OnPermissionPropertyChanged));
public static readonly DependencyProperty RoleProperty =
DependencyProperty.RegisterAttached("Role", typeof(string), typeof(PermissionBehavior),
new PropertyMetadata(OnRolePropertyChanged));
private static void OnPermissionPropertyChanged(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs e)
{
SetPermission(dependencyObject, (Permission) e.NewValue);
}
public static void SetPermission(DependencyObject obj, Permission value)
{
var behavior = GetAttachedBehavior(obj as FrameworkElement);
behavior.AssociatedObject = obj as FrameworkElement;
obj.SetValue(PermissionProperty, value);
behavior.CurrentPermission = value;
behavior.UpdateVisibility();
}
public static object GetPermission(DependencyObject obj)
{
return obj.GetValue(PermissionProperty);
}
private static void OnRolePropertyChanged(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs e)
{
SetRole(dependencyObject, (string) e.NewValue);
}
public static void SetRole(DependencyObject obj, string value)
{
var behavior = GetAttachedBehavior(obj as FrameworkElement);
behavior.AssociatedObject = obj as FrameworkElement;
obj.SetValue(RoleProperty, value);
behavior.RoleList = value.Split(',').ToList();
behavior.UpdateVisibility();
}
public static object GetRole(DependencyObject obj)
{
return obj.GetValue(RoleProperty);
}
private static PermissionBehavior GetAttachedBehavior(FrameworkElement obj)
{
if (!Instances.ContainsKey(obj))
{
Instances[obj] = new PermissionBehavior { AssociatedObject = obj };
}
return Instances[obj];
}
static PermissionBehavior()
{
}
// Class instance parameters
private FrameworkElement AssociatedObject { get; set; }
private Permission CurrentPermission { get; set; }
private List<string> RoleList { get; set; }
private void UpdateVisibility()
{
if(RoleList == null || CurrentPermission == null)
return;
if (RoleList.Intersect(CurrentPermission.Roles).Any())
{
AssociatedObject.Visibility = Visibility.Visible;
AssociatedObject.IsEnabled = true;
}
else
{
AssociatedObject.Visibility = Visibility.Hidden;
AssociatedObject.IsEnabled = false;
}
}
}
XAML
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:WpfApplication2"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
<Button Content="Requires Admin" Margin="6" my:PermissionBehavior.Permission="{Binding UserPermission, Mode=TwoWay}" my:PermissionBehavior.Role="Admin"/>
<Button Content="Requires User" Margin="6" my:PermissionBehavior.Permission="{Binding UserPermission, Mode=TwoWay}" my:PermissionBehavior.Role="User"/>
</StackPanel>
<Button Content="Change user" HorizontalAlignment="Left" Margin="10,88,0,0" VerticalAlignment="Top" Width="75" Click="ButtonBase_OnClick"/>
</Grid>
</Window>
代码
public partial class MainWindow : Window, INotifyPropertyChanged
{
private Permission userPermission;
public Permission UserPermission
{
get { return userPermission; }
set
{
userPermission = value;
OnPropertyChanged("UserPermission");
}
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
UserPermission = new Permission {Roles = new List<string>{"Admin","DumbUser"}};
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
var p = new Permission();
p.Roles = new List<string> {"User", "Supervisor"};
UserPermission = p;
}
}
我认为,根据您使用的内容更改我的 Permission 对象和逻辑是微不足道的.
It's trivial to change my Permission object and logic with what you use, I would think.
这篇关于动态分配 UI 权限 WPF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!