动态分配UI权限WPF [英] Assign UI Permissions WPF dynamically

查看:96
本文介绍了动态分配UI权限WPF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能重复:
在背后的代码中设置WPF UI权限

Possible Duplicate:
Setting WPF UI Permissions in Code Behind

我开始使用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.

任何帮助将不胜感激.

Noel.

推荐答案

您可以尝试使用行为".我创建了一些简单的代码,您可以看一下:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆