我有一个用户权限的枚举类型,如下所示:
[Flags]
public enum UserPrivileges : byte
{
None = 0, // 0000 0000
View = 1 << 0, // 0000 0001
Import = 1 << 1, // 0000 0010
Export = 1 << 2, // 0000 0100
Supervisor = View | Import | Export | 1 << 3, // 0000 1111
Admin = Supervisor | 1 << 4 // 0001 1111
}
这些值通过值转换器绑定到 GUI 中的 CheckBoxes。(我想尽可能通用,因为还有不同的权限 [例如 EmployeePrivileges])
public class ByteFlagsEnumValueConverter : IValueConverter
{
private byte _targetValue;
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
var mask = (byte)parameter;
_targetValue = (byte)value;
return ((mask | _targetValue) == _targetValue);
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
var mask = (byte)parameter;
if ((bool)value)
{
_targetValue |= mask;
}
else
{
// Get next superflag for mask (e.g. 0110 -> 1111)
var b = mask;
b--;
b |= (byte)(b >> 1);
b |= (byte)(b >> 2);
b |= (byte)(b >> 4);
b |= (byte)(b >> 8);
// if you remove a superflag (e.g. 1111) also remove
// everything higher than this flag
if (mask == b || mask == 1)
_targetValue &= (byte)(mask >> 1);
else
// ????????
}
return Enum.Parse(targetType, _targetValue.ToString());
}
}
这对于在 GUI 中向用户显示和添加权限非常有效。它也适用于删除 Superflags,如 Supervisor(所有标志>=
Supervisor 都被删除,其他标志不会改变)。
问题是,例如,当我取消选中导入时,我想删除所有超级标志(主管、管理员)但想保留其他标志(查看、导出)。
0001 1111 // Admin
0000 0010 // Import
---------
0000 0101 // View | Export
但我还没有想出一个好主意如何实现这一点。有哪位大侠有好的解决办法吗?