[英]MVVM UI Control user dependent Visibility with WPF
這更多是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);
}
}
}
這是我聲明和綁定菜單的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>
現在在這里我的要求:
到目前為止我的兩個選擇
什么是最干凈的方法基於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集合。 即您的MainViewModel必須知道允許用戶查看哪些菜單項。
即,您可以在MainViewModel的構造函數中使用如下代碼:
_MainMenu = new ObservableCollection<MenuItemModel>(_allMenuItems.Select(m => IsVisibleToUser(m)));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.