动态分配 UI 权限 WPF [重复]

2023-12-12

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

我开始使用 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="{绑定源={x:Static systhread:Thread.CurrentPrincipal}, ConverterParameter=admin;editor;readonly, Converter={rv:RoleToVisibilityConverter}}

注意:我还需要将 xmlns:systhread="clr-namespace:System.Threading; assembly=mscorlib" 添加到 MainWindow.xaml 中。

我的问题是:

上面的示例是实现此目的的最佳方法还是(正如我所想的)动态加载可见性绑定。

任何帮助,将不胜感激。

Noel.


您可以尝试使用行为来代替。我创建了一些简单的代码,您可以查看:

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>

Code

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 对象和逻辑是微不足道的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态分配 UI 权限 WPF [重复] 的相关文章

随机推荐

  • vtkOBJReader 将 OBJ 作为单独的 vtkPolyData 对象导入

    我的目的是获得 vtkPolyData 通过 vtk OBJ 导入实现理想的颜色 纹理 传递给 k3d 查看器使用 k3d vtk poly data
  • 如何将单维索引转换为多维数组中的相应索引?

    假设我有一个 3x4x5x6 java 双精度数组a我展开到 ArrayList 中b长度为 360 的方式如下 for int i 0 i
  • C#:将 DataTable 绑定到 GridView 时更改列的顺序

    如何更改数据表中列的显示顺序 例如 数据表 dt 包含两列 a 和 b 我将它绑定到 GridView 如下所示 gridView DataSource dt gridView DataBind 但我希望 GridView 首先显示 b 最
  • 如何加速 VBA 宏

    我正在使用宏生成新工作表 对于新工作表生成 数据是从 4 个以上的 MS Access DB 中检索的 每个 DB 至少有 200 个字段 我的宏代码包括 1 Cell locking 2 Alignment and formatting
  • 如何在 Xamarin Forms(Android 和 iOS)中实现 Google 地图? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我有一个 Google 地图 API 密钥 我想用它来使用 Xamarin Forms 在我的 Android 应用程序和 iOS 应用程序中显示地图 您会使用哪个库来减少两个操
  • 检查样式配置中的 IntelliJ IDEA 代码格式

    我决定为 android maven 插件做出贡献 他们使用非常特定的代码风格格式 我需要一些时间来修改IDEA代码格式规则以满足他们的要求 幸运的是有 checkstyle 配置 我已经为 IDEA 安装了检查式插件 并立即看到我当前的格
  • 如何删除 psql(PostgreSQL 交互式终端)中以常用单词开头的所有表?

    如何删除名称开头的所有表 例如doors 我可以使用某种正则表达式吗drop table命令 我不喜欢编写自定义脚本 但欢迎所有解决方案 谢谢 该脚本将生成 DDL 命令来删除它们 SELECT DROP TABLE t oid regcl
  • 在圆形数组中搜索

    在圆形数组中搜索的最佳方法是什么 Example 1 array 45 67 44 11 49 4 56 12 39 90 circular array 11 49 4 56 12 39 90 45 67 二分搜索是正确的开始方法吗 二分查
  • IntelliJ IDEA 仅运行突出显示的代码

    如何仅在 IntelliJ IDEA 中运行突出显示的代码 有时您不需要运行整个文件 而只想运行某些数量的代码 IntelliJ IDEA中有这样的选择吗 有可能计算任意表达式 Run Evaluate Expression 要评估代码片段
  • 表格大小与页面布局

    我在 Oracle Linux Server 6 3 版上使用 PostgreSQL 9 2 根据存储布局文档 页面布局包含 页头数据 24 字节 n 项 索引项 表项 的点数 AKA ItemIdData 4 字节 可用空间 n 个项目
  • Java - PaintComponent 中的 MouseListener 操作事件

    这里我有一个代码 它使用paintComponent在鼠标单击的位置上绘制一个矩形 我可以获得输出消息 但与图形和 draw 相关的任何内容都不起作用 Code import java awt import java awt event i
  • 仅解码 URL 非 ascii 字符

    现在我正在研究维基百科 在很多文章中 我注意到一些网址 例如 https www google com search q 26 E0 B8 89 E0 B8 B1 E0 B8 99 都很长 示例 URL 可以替换为 https www go
  • WPF UserControl 不继承父 DataContext

    我正在尝试开发一个可重用的用户控件 但遇到了绑定问题 我创建了一个较小的应用程序来测试它 但无法解决它 或者至少无法理解为什么它没有按照我的预期工作 代码如下 我期望的是我放在 MainWindow xaml 上的 TestUserCont
  • 转换颜色以模仿灰度打印

    读书时这个问题 我开始思考是否可以转换颜色来模仿普通的灰度打印机 假设您的屏幕已校准 找到一个可认可的近似值可以节省纸张 例如 如何转换这些颜色 看看在纸上是否可以区分浅蓝色和深蓝色和红色 temp lt rgb2hsv 239 138 9
  • 使用accepts_nested_attributes_for创建新记录或更新现有记录

    阅读重大更新以获取最新信息 嘿大家 我在 Rails 应用程序中有一个多对多关系 涉及三个表 用户表 兴趣表和连接 user interests 表 该表也有一个评级值 以便用户可以对他们的每个兴趣进行评级1 10 级 我基本上是在寻找一种
  • EF Core 5.0 - 更新 ASP.NET Core Web API 中的多对多实体

    EF Core 5 0 引入了多对多关系 我陷入了如何通过我的 asp net api 更新它们的困境 对于一对一和一对多关系 有一个约定 只需添加属性名称后跟 ID public class Blog public int BlogId
  • 找不到或无法加载程序集 mscorlib.dll

    首先 我见过这个问题 虽然问题看起来相似 但其实并不相同 我正在运行一个精简的单声道 没有使用 4 5 配置文件构建 configure with profile4 yes with profile4 5 no 我有一个针对 NET 4 0
  • Groupby 与 TimeGrouper“向后”

    我有一个DataFrame包含时间序列 rng pd date range 2016 06 01 periods 24 7 freq H ones pd Series 1 24 7 rng rdf pd DataFrame a ones 最
  • 从透明形式的图像中删除轮廓

    我正在尝试将窗口形式转换为透明 并使其仅显示一个对象 但它在我的对象周围仍然有一条线 描边 它并不像我想要的那么完美 如何取出线条 笔画 附上图片对比一下 这是我的代码 private void Form1 Load object send
  • 动态分配 UI 权限 WPF [重复]

    这个问题在这里已经有答案了 可能的重复 在代码隐藏中设置 WPF UI 权限 我开始使用 WPF 并希望创建一个应用程序 该应用程序将根据用户 AD 及其角色 自定义 显示 隐藏控件 我设法通过使用继承 MarkupExpension 和