I have an enum type for user privileges that looks like this:
[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
}
These values are bound to CheckBoxes in the GUI with a value converter. (I wanted to do this as generic as possible because there are also different privileges [e.g. 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());
}
}
This works really fine for displaying and adding privileges to the user in the GUI. Also it works for removing Superflags like Supervisor (all flags >=
Supervisor get removed, the other flags don't change).
The problem is when I uncheck Import for example, I want to remove all Superflags (Supervisor, Admin) but would like to keep the other flags (View, Export).
0001 1111 // Admin
0000 0010 // Import
---------
0000 0101 // View | Export
But I haven't come up with an good idea how to accomplish this. Anyboy who has a good solution for this?
If I understand what you want , this should do the job
byte tmp = 1 << 3 | 1 << 4;
byte removeSuperFlagMask = (byte) (~tmp);
byte notSuperflagsMask = 1 << 3 | 1 << 2 | 1 << 1;
if ((valueToRemove & notSuperflagsMask) != 0)
{
newValue = (byte)(removeSuperFlagMask & currentValue & ~valueToRemove);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With