动态分配 UI 权限 WPF [重复]
Posted
技术标签:
【中文标题】动态分配 UI 权限 WPF [重复]【英文标题】:Assign UI Permissions WPF dynamically [duplicate] 【发布时间】:2013-01-03 09:18:04 【问题描述】:可能重复:Setting WPF UI Permissions in Code Behind
我开始使用 WPF 并希望创建一个应用程序,该应用程序将根据用户 (AD) 和他的角色(自定义) 显示/隐藏控件。
我设法通过使用继承 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 中,我为可见性添加了以下绑定:
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。
我的问题是:
上面的例子是实现这一点的最佳方式还是(正如我所想的)动态加载可见性绑定的最佳方式。
任何帮助将不胜感激。
诺埃尔。
【问题讨论】:
好的,看来我的问题有点含糊,所以重新问了一遍,得到了答案。基本上,我希望在代码隐藏中而不是在 xaml 中设置 UI 权限。看起来这不是一个好主意。在这里查看答案。 ***.com/questions/14257877/… 感谢所有回复。 【参考方案1】:您可以尝试改用行为。我创建了一些您可以查看的简单代码:
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 对象和逻辑是微不足道的。
【讨论】:
您好 Akselk,感谢您的回复。让你的代码运行起来,会派上用场。但我认为我的问题不够清楚。我希望避免在 xaml 中设置权限,而是将其放在后面的代码中。我想得越多,我认为这不是一个好主意。你怎么看? 谢谢!这将是有史以来最好的解决方案。以上是关于动态分配 UI 权限 WPF [重复]的主要内容,如果未能解决你的问题,请参考以下文章
动态分配数组时的C ++ new vs new [] [重复]