Clear privilege enumeration checkboxes correctly in C #

I have an enumeration 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 a graphical interface with a value converter. (I wanted to make this as general as possible, because there are other privileges (like 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 (eg 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 (eg 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 great for displaying and adding privileges to a user in a graphical interface. It also works to remove Superflags as a Supervisor (all flags >= Supervisor are removed, other flags do not change).

The problem is that I will clear the "Import" checkbox, for example, I want to remove all Superflags (Supervisor, Admin), but would like to save other flags (View, Export).

 0001 1111 // Admin 0000 0010 // Import --------- 0000 0101 // View | Export 

But I didn’t figure out how to do it. Anyboy who has a good solution for this?

+6
source share
3 answers

Mfz returned me correctly, but for me it was not general enough, so I came up with a different solution:

  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { var mask = (byte)parameter; if ((bool)value) { _targetValue |= mask; } else { if (IsSuperFlag(mask) && mask != 1) _targetValue &= (byte)(mask >> 1); else { // Get all flags from enum type that are no SuperFlags var flags = Enum.GetValues(targetType).Cast<Enum>(); flags = flags.Where(x => !IsSuperFlag(System.Convert.ToByte(x))); long nonSuperFlags = 0; foreach (var flag in flags) { nonSuperFlags |= System.Convert.ToByte(flag); } // Now only remove everything except the nonSuperFlags // and then remove the mask _targetValue &= (byte)(~(_targetValue ^ nonSuperFlags | mask)); } } return Enum.Parse(targetType, _targetValue.ToString()); } private bool IsSuperFlag(byte flag) { var b = flag; b--; b |= (byte)(b >> 1); b |= (byte)(b >> 2); b |= (byte)(b >> 4); b |= (byte)(b >> 8); return b == flag; } 

I just got all non-super flags for the enum type, and they only removed super flags and subsequently removed the flag.

0
source

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); } 
+2
source

If I understood correctly, you want to remove Supervisor and Admin like this:

 UserPrivileges newPrivileges = (UserPrivileges)(((byte)currentPrivileges) & 7; 

He will act as follows:

 0001 1111 // Admin 0000 0111 // 7 flag --------- 0000 0111 // Remain only where 7 bit was set. 

Another example

 0000 0011 // View | Import 0000 0111 // 7 flag --------- 0000 0011 // Remain only where 7 bit was set. 

As before, I mean that where flag 7 , it will save the value as a result (beein 0 or 1 ). And where the flag is 7 0 , it will kill the value 0 .

+1
source

Source: https://habr.com/ru/post/946587/


All Articles