如何使用枚举器控制 XAML 中的角色/权限

发布于 2024-11-30 22:07:10 字数 294 浏览 0 评论 0原文

问题是我有权限而不是角色。

我有数据库驱动的权限,我通过登录 Silverlight 应用程序为每个用户获取这些权限,并将它们填充到 List 中。我还有一个用于 C# 代码的枚举器。

无论如何,我不想谈论为什么我不使用角色等。

我想在 XAML 元素中输入我的权限并在它们上设置 Visibility 和 IsEnabled。

像这样:

<Button IsEnabled="{Binding IsAdmin}" />

The problem is that I have permissions and not roles.

I have database driven permissions and I get them for each user via logon in the Silverlight application and fill them into a List. I also have an enumerator for the C# code.

Anyways I do not wish to talk about why I am not using roles etc.

I want to type my permission into XAML elements and set Visibility and IsEnabled on them.

Like this:

<Button IsEnabled="{Binding IsAdmin}" />

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你在看孤独的风景 2024-12-07 22:07:10

首先是附加的依赖属性:

using System;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
//using GalaSoft.MvvmLight; //optional

 namespace SL.Permissions
 {
    public enum EnumPermission : short
    {
        ADMIN = 1,  //Administrator
        EDITOR = 2, //Editor
        USER = 99 //normal user
    }

    public class Permission
    {

        #region private methods

        private static void RecalculateControlVisibility(UIElement control, bool hasPermission)
        {
            if (hasPermission)
                control.Visibility = Visibility.Visible;
            else
                control.Visibility = Visibility.Collapsed;
        }

        private static void RecalculateControlIsEnabled(Control control, bool hasPermission)
        {
            control.IsEnabled = hasPermission;
        }

        #endregion

        #region Visibility

        public static readonly DependencyProperty VisibilityProperty =
            DependencyProperty.RegisterAttached("Visibility", typeof(string), typeof(Permission), new PropertyMetadata(Visibility_Callback));

        private static void Visibility_Callback(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            bool hasPermission = false;

            var uiElement = (UIElement)source;
            var permissions = GetVisibility(uiElement).Split(',');
            EnumPermission permission = new EnumPermission();

            //if using MVVM-light toolkit
            //if (ViewModelBase.IsInDesignModeStatic)
            //{
            //  hasPermission = true;
            //  goto END;
            //}

            //loop trough enumerator
            foreach (var fieldInfo in permission.GetType().GetFields(BindingFlags.Static | BindingFlags.Public))
            {
                //loop trough parameters
                foreach (var item in permissions.Where(m => m.ToUpper() == fieldInfo.Name.ToUpper()))
                {
                    permission = (EnumPermission)Enum.Parse(permission.GetType(), fieldInfo.Name, false);
                    //hasPermission = HasUserPermission(permission); //check if this permission is in users permission list
                    hasPermission = true; //TODO: place here your code to check permission of user
                    if (hasPermission) goto END;
                }
            }

            goto END;

        END:
            RecalculateControlVisibility(uiElement, hasPermission);
        }

        public static void SetVisibility(UIElement element, string value)
        {
            element.SetValue(VisibilityProperty, value);
        }

        public static string GetVisibility(UIElement element)
        {
            return (string)element.GetValue(VisibilityProperty);
        }

        #endregion

        #region IsEnabled

        public static readonly DependencyProperty IsEnabledProperty =
            DependencyProperty.RegisterAttached("IsEnabled", typeof(string), typeof(Permission), new PropertyMetadata(IsEnabled_Callback));

        private static void IsEnabled_Callback(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            bool hasPermission = false;

            var uiElement = (Control)source;
            var permissions = GetIsEnabled(uiElement).Split(',');
            EnumPermission permission = new EnumPermission();

            //if using MVVM-light toolkit
            //if (ViewModelBase.IsInDesignModeStatic)
            //{
            //  hasPermission = true;
            //  goto END;
            //}

            //loop trough enumerator
            foreach (var fieldInfo in permission.GetType().GetFields(BindingFlags.Static | BindingFlags.Public))
            {
                //loop trough parameters
                foreach (var item in permissions.Where(m => m.ToUpper() == fieldInfo.Name.ToUpper()))
                {
                    permission = (EnumPermission)Enum.Parse(permission.GetType(), fieldInfo.Name, false);
                    //hasPermission = HasUserPermission(permission); //check if this permission is in users permission list
                    hasPermission = true; //TODO: place here your code to check permission of user
                    if (hasPermission) goto END;
                }
            }

            goto END;

        END:
            RecalculateControlIsEnabled(uiElement, hasPermission);
        }

        public static void SetIsEnabled(UIElement element, string value)
        {
            element.SetValue(IsEnabledProperty, value);
        }

        public static string GetIsEnabled(UIElement element)
        {
            return (string)element.GetValue(IsEnabledProperty);
        }

        #endregion
    }
}

XAML 命名空间代码:

 xmlns:permissions="clr-namespace:SL.Permissions"

XAML 中的按钮:

<Button Content="Save" permissions:Permission.IsEnabled="ADMIN,EDITOR" Command={Binding SaveClickCommand} />

因此,仅对具有 ADMIN 或 EDITOR 权限的用户启用此按钮

<Button Content="Save" permissions:Permission.Visibility="ADMIN" Command={Binding SaveClickCommand} />

仅此按钮将可见对于具有 ADMIN 权限的用户

当然,您不仅限于仅使用按钮。

我愿意接受任何代码优化评论或有关此解决方案的一般评论。

TODO:您必须实现您自己的方法来检查用户是否具有权限,

我使用我的方法hasPermission = HasUserPermission(permission); 它会在我通过登录为用户获得的权限列表中查找可枚举权限。

我错过了什么:对此的完美解决方案是对 XAML 中的所有权限进行智能感知,但由于我想设置多个权限,所以它有点无用。

如果您只想使用一种权限并希望智能感知向您显示可以使用的权限,只需将附加的依赖属性更改为此(例如,对于可见性,您必须对 IsEnabled 执行相同的操作):

    public static readonly DependencyProperty VisibilityProperty = 
        DependencyProperty.RegisterAttached("Visibility", typeof(EnumPermission), typeof(Permission), new PropertyMetadata(Visibility_Callback));

我已经设置了第二个参数 (Type propertyType) 为 EnumPermission 而不是 string,这将使 XAML 中的智能感知能够向您显示枚举器的权限。

First the Attached dependency property:

using System;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
//using GalaSoft.MvvmLight; //optional

 namespace SL.Permissions
 {
    public enum EnumPermission : short
    {
        ADMIN = 1,  //Administrator
        EDITOR = 2, //Editor
        USER = 99 //normal user
    }

    public class Permission
    {

        #region private methods

        private static void RecalculateControlVisibility(UIElement control, bool hasPermission)
        {
            if (hasPermission)
                control.Visibility = Visibility.Visible;
            else
                control.Visibility = Visibility.Collapsed;
        }

        private static void RecalculateControlIsEnabled(Control control, bool hasPermission)
        {
            control.IsEnabled = hasPermission;
        }

        #endregion

        #region Visibility

        public static readonly DependencyProperty VisibilityProperty =
            DependencyProperty.RegisterAttached("Visibility", typeof(string), typeof(Permission), new PropertyMetadata(Visibility_Callback));

        private static void Visibility_Callback(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            bool hasPermission = false;

            var uiElement = (UIElement)source;
            var permissions = GetVisibility(uiElement).Split(',');
            EnumPermission permission = new EnumPermission();

            //if using MVVM-light toolkit
            //if (ViewModelBase.IsInDesignModeStatic)
            //{
            //  hasPermission = true;
            //  goto END;
            //}

            //loop trough enumerator
            foreach (var fieldInfo in permission.GetType().GetFields(BindingFlags.Static | BindingFlags.Public))
            {
                //loop trough parameters
                foreach (var item in permissions.Where(m => m.ToUpper() == fieldInfo.Name.ToUpper()))
                {
                    permission = (EnumPermission)Enum.Parse(permission.GetType(), fieldInfo.Name, false);
                    //hasPermission = HasUserPermission(permission); //check if this permission is in users permission list
                    hasPermission = true; //TODO: place here your code to check permission of user
                    if (hasPermission) goto END;
                }
            }

            goto END;

        END:
            RecalculateControlVisibility(uiElement, hasPermission);
        }

        public static void SetVisibility(UIElement element, string value)
        {
            element.SetValue(VisibilityProperty, value);
        }

        public static string GetVisibility(UIElement element)
        {
            return (string)element.GetValue(VisibilityProperty);
        }

        #endregion

        #region IsEnabled

        public static readonly DependencyProperty IsEnabledProperty =
            DependencyProperty.RegisterAttached("IsEnabled", typeof(string), typeof(Permission), new PropertyMetadata(IsEnabled_Callback));

        private static void IsEnabled_Callback(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            bool hasPermission = false;

            var uiElement = (Control)source;
            var permissions = GetIsEnabled(uiElement).Split(',');
            EnumPermission permission = new EnumPermission();

            //if using MVVM-light toolkit
            //if (ViewModelBase.IsInDesignModeStatic)
            //{
            //  hasPermission = true;
            //  goto END;
            //}

            //loop trough enumerator
            foreach (var fieldInfo in permission.GetType().GetFields(BindingFlags.Static | BindingFlags.Public))
            {
                //loop trough parameters
                foreach (var item in permissions.Where(m => m.ToUpper() == fieldInfo.Name.ToUpper()))
                {
                    permission = (EnumPermission)Enum.Parse(permission.GetType(), fieldInfo.Name, false);
                    //hasPermission = HasUserPermission(permission); //check if this permission is in users permission list
                    hasPermission = true; //TODO: place here your code to check permission of user
                    if (hasPermission) goto END;
                }
            }

            goto END;

        END:
            RecalculateControlIsEnabled(uiElement, hasPermission);
        }

        public static void SetIsEnabled(UIElement element, string value)
        {
            element.SetValue(IsEnabledProperty, value);
        }

        public static string GetIsEnabled(UIElement element)
        {
            return (string)element.GetValue(IsEnabledProperty);
        }

        #endregion
    }
}

The XAML namespace code:

 xmlns:permissions="clr-namespace:SL.Permissions"

The button in XAML:

<Button Content="Save" permissions:Permission.IsEnabled="ADMIN,EDITOR" Command={Binding SaveClickCommand} />

So this button will be enabled only for users with ADMIN or EDITOR permissions

<Button Content="Save" permissions:Permission.Visibility="ADMIN" Command={Binding SaveClickCommand} />

This button will be visible only for user with ADMIN permissions

Of course you are not limited to use this only with buttons.

I am open for any code optimization comments or comments in general about this solution.

TODO: you will have to implement your own method to check if the user has permissions

I did that with my method hasPermission = HasUserPermission(permission); which looks up the enumrable permission in the List of permissions I get for the user via logon.

What I miss: The perfect solution for this would be intellisense for all the permissions in XAML, but since I want to set more than one permission it's kind of useless.

If you want to use only one permission and want intellisense to show you the permissions you can use, just change the attached dependency property to this (example for Visibility, you'll have to do the same for IsEnabled):

    public static readonly DependencyProperty VisibilityProperty = 
        DependencyProperty.RegisterAttached("Visibility", typeof(EnumPermission), typeof(Permission), new PropertyMetadata(Visibility_Callback));

I have set the second parameter (Type propertyType) to EnumPermission instead of string, that will enable intellisense in XAML to show you permissions from your enumerator.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文