gpt4 book ai didi

c# - MVVM UI 使用 WPF 控制用户依赖的可见性

转载 作者:行者123 更新时间:2023-12-03 10:55:37 24 4
gpt4 key购买 nike

这更像是一个 MVVM 应用程序设计问题。我正在尝试实现一个非常基本的基于用户的权限管理,其中我的应用程序中某些控件的可见性来自当前用户角色。这是我的简化模型:

public class User
{
public string UserName {get;set;}
public Role UserRole {get;set;}
}

public enum Role
{
Developer,
BusinessAnalyst
}

public class MenuItemModel
{
public ICommand Command {get;set;}
public string Header {get;set;}
public bool Visible {get;set;}
private List<MenuItemModel> _Items;
public List<MenuItemModel> Items
{
get { return _Items ?? (_Items = new List<MenuItemModel>()); }
set
{
_Items = value;
}
}
}

我的 MainViewModel 包含以下属性:
public class MainViewModel : ViewModelBase<MainViewModel>
{
private ObservableCollection<MenuItemModel> _MainMenu;
public ObservableCollection<MenuItemModel> MainMenu
{
get { return _MainMenu; }
set
{
_MainMenu = value;
NotifyPropertyChanged(x=>x.MainMenu);
}
}
private User _CurrentUser;
public User CurrentUser
{
get { return _CurrentUser; }
set {
_CurrentUser = value;
NotifyPropertyChanged(x=>x.CurrentUser);
}
}
}

这是我声明和绑定(bind)菜单的 XAML:
<Menu DockPanel.Dock="Top" ItemsSource="{Binding Path=MainMenu}">
<Menu.ItemContainerStyle>
<Style>
<Setter Property="MenuItem.Header" Value="{Binding Path=Header}"/>
<Setter Property="MenuItem.ItemsSource" Value="{Binding Path=Items}"/>
<!-- How to bind Visibility????-->
<!--Setter Property="MenuItem.Visibility" /-->
</Style>
</Menu.ItemContainerStyle>
</Menu>

现在这里是我的要求:
  • 某些 UI 控件(例如 MenuItems)的可见性取决于 User.Role。例如: MenuItemA 应该对 Role.Developer 可见,但对 Role.BusinessAnalyst 不可见
  • 某些控件可能对多个角色可见(例如开发人员和业务分析师)

  • 到目前为止我的两个选择
  • 创建一个自定义转换器,该转换器具有根据允许的角色派生可见性的逻辑并将其绑定(bind)到 MenuItem.Visibility 值属性。这样做的问题: a) 允许此控件的角色需要在运行时传递,因为它们来自数据库,并且您不能将 CommandParameters 绑定(bind)到角色集合。 b) 转换器如何访问 User.Role 以获取可见性?
  • 在我的 UI 模型(例如 MenuItemModel)的属性中创建可见性逻辑。但是在这里我不想在我的 User 和 MenuItemModel 类之间创建依赖关系。

  • 什么是基于 User.Role 动态派生 UI 控件可见性而不遇到紧密耦合的场景(依赖项)的最简洁方法?

    谢谢!

    解决方案:所以这就是我根据@fmunkert 的建议最终解决它的方式。请注意,我必须将 MenuItemModel.Items 属性更改为 List 才能访问“RemoveAll”方法:
        public MainViewModel()
    {
    //Create a new User with a Role
    InitializeUser();
    //Get all the Menus in the application
    List<MenuItemModel> allItems = GetAllMenus();
    //Remove recursively all Items that should not be visible for this user
    allItems.RemoveAll(x=>!IsVisibleToUser(x));
    //Set my MainMenu based on the filtered Menu list
    _MainMenu = new ObservableCollection<MenuItemModel>(allItems);
    }

    private void InitializeUser()
    {
    CurrentUser = new User {UserName = "apsolis", UserRole = Role.Developer};
    }

    这是我的 MainViewModel中的方法递归删除禁止项目:
        /// <summary>
    /// Method to check if current MenuItem is visible to user
    /// and remove items that are forbidden to this user
    /// </summary>
    /// <param name="m"></param>
    /// <returns></returns>
    public bool IsVisibleToUser(MenuItemModel m)
    {
    if (m.Items != null && m.Items.Count > 0)
    {
    m.Items.RemoveAll(y=>!IsVisibleToUser(y));
    }
    return m.Roles == null || m.Roles.Contains(CurrentUser.UserRole);
    }

    这似乎工作正常

    最佳答案

    由于您在 ViewModel 中生成菜单项,我建议不要使用 MenuItem.Visibility一点也不。相反,让您的 ViewModel 确定允许用户查看哪些菜单项,并仅使用该菜单项子集填充 MainMenu 集合。 IE。您的 MainViewModel 必须知道允许用户查看哪些菜单项。

    即,您将在 MainViewModel 的构造函数中使用类似的内容:

    _MainMenu = new ObservableCollection<MenuItemModel>(_allMenuItems.Select(m => IsVisibleToUser(m)));

    关于c# - MVVM UI 使用 WPF 控制用户依赖的可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10653758/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com