3

A previous developer (who no longer works with us, so I can't ask him) has done something pretty slick, that I really do not understand. We have this enum:

   [Flags]
    public enum SidingTypePreference
    {
        [Value(Name = "Vinyl")]
        Vinyl = 1,
        [Value(Name = "Metal or Aluminum")]
        MetalOrAluminum = 2,
        [Value(Name = "Composite")]
        Composite = 4,
        [Value(Name = "Wood")]
        Wood = 8,
        [Value(Name = "Other")]
        Other = 16
    }

In the database, SidingTypes is stored as a single int, which is a sum of all the values selected.

enter image description here

In the Model:

public SidingTypePreference? SidingTypes { get; set; }

In the controller, where table is just a row result from a query:

Model.SidingTypes = table.SidingTypes

And in the view:

@Html.EditorFor(m => Model.SidingTypes, new { @class = "form-control input-sm", GroupID = "SidingTypePreference", Cols = 1 })

But, here's the part I don't understand. Let's say that SidingTypes = 10. By some sort of voodoo magic, that int is translated into:

<input type="checkbox" class="..." name="SidingTypes_0" value="1">  Vinyl
<input type="checkbox" class="..." name="SidingTypes_1" value="2" checked>  Metal or Aluminum
<input type="checkbox" class="..." name="SidingTypes_2" value="4"> Composite
<input type="checkbox" class="..." name="SidingTypes_3" value="8" checked> Wood
<input type="checkbox" class="..." name="SidingTypes_4" value="16"> Other

(class redacted just to prevent the need to scroll, but they are all 'lookup-checkbox-SidingTypes'.)

From the value of that int, it knows which are checked and which are not.

FIRST QUESTION: Is this native .NET? Or is there some extension method or template that I need to find?

SECOND QUESTION: What I need to do, independent of anything else, is to build a method to determine if an enum is selected.

Something like:

private bool IsSelected(int SidingTypes, SidingTypePreference sidingTypePreference)
{
  ... ?? ...
  return true or false;
}
Casey Crookston
  • 13,016
  • 24
  • 107
  • 193
  • 4
    Well, enums with the `Flags` attribute decompose a value into the equivalent bits that would make up that composite value (e.g. `10 = 2 + 8`) I suspect there is a custom template in the project somewhere to convert the enum value into a set of checkboxes. – D Stanley Feb 01 '17 at 19:18
  • 1
    Check this out: https://msdn.microsoft.com/en-us/library/system.flagsattribute(v=vs.110).aspx also this post has a very nice answer: http://stackoverflow.com/questions/8447/what-does-the-flags-enum-attribute-mean-in-c – Magnetron Feb 01 '17 at 19:23
  • Refer [this answer](http://stackoverflow.com/questions/37990786/how-to-reduce-code-duplication-in-asp-net-mvc-view-when-working-with-flags-enum/37991402#37991402) for working with enums with the `[Flags]` attribute –  Feb 01 '17 at 21:19

2 Answers2

2

Last I checked (a couple of years ago now), ASP.NET MVC didn't have a built-in template for flags enums like this. However, it's likely that the developer created a custom editor template to recognize this type (or maybe flag enums generally) and display an editor for it.

Check out the files in Views/Shared/EditorTemplates/--particularly ones named SidingTypePreference.cshtml or Object.cshtml. It might also help to do a full-text search for lookup-checkbox- anywhere in your project.

For your second question, D Stanley's answer is correct: you use a bitwise & operator against the value that you're interested in, and then check to see if the result is non-zero.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • 1
    Thank you!! And your hint to do a search for lookup-checkbox was spot on. Found the template. – Casey Crookston Feb 01 '17 at 19:26
  • Also, I have to ask about your user name... StriplingWarrior. Mind if I ask what that's from :-) ? – Casey Crookston Feb 01 '17 at 19:27
  • @CaseyCrookston: There's an account in the Book of Mormon about a company of young soldiers who exhibited such faith that they received divine protection in battle. They're referred to as "stripling soldiers" in the scripture, but in modern LDS culture they're often referred to as [Stripling Warriors](https://en.wikipedia.org/wiki/Two_thousand_stripling_warriors). "Stripling" just means "young." I adopted the username/email when I was younger and haven't bothered updating it as I age. :-) – StriplingWarrior Feb 01 '17 at 20:38
  • Ok, that's what I figured :-) It caught my eye. Go Armies of Helaman! – Casey Crookston Feb 01 '17 at 20:49
2

Is this native .NET?

Part of it is. Enums with the Flags attribute decompose a value into the equivalent bits that would make up that composite value (e.g. 10 = 2 + 8)

Converting that value into a set of checkboxes is not native. I suspect there is a custom template in the project somewhere to convert the enum value into a set of checkboxes

How do I determine if an enum is selected.

Just use bitwise operations:

private bool IsSelected(int SidingTypes, SidingTypePreference sidingTypePreference)
{
  return (SidingTypes & (int)sidingTypePreference) != 0;
}

Since the & operator will return a number with the bits that are "selected" in both SidingTypes and sidingTypePreference. If no flags match, the result will be all zeros; so any number other than 0 indicates a match.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • 1
    There's a method on Enum, HasFlag(Enum flag) method that does that check. – Fran Feb 01 '17 at 19:27
  • Ok thanks D Stanley. But, one question. In your example above, I get: Operator '&' can not be applied to operands of type Int and SidingTypePrefrences – Casey Crookston Feb 01 '17 at 19:30
  • @CaseyCrookston I missed that you're checking an int versus an enum. I added a cast to int to allow the operation. – D Stanley Feb 01 '17 at 19:31
  • 1
    @Fran True, but the input is an `int` not a `SidingTypePreference` so you'd have to cast the int value to an equivalent enum. Plus there is some type-safety overhead with `HasFlag`. Since we're already not type-safe that overhead is not necessary. – D Stanley Feb 01 '17 at 19:33
  • true. I am doing an Enum.Parse() to put my int into a the flag values. – Fran Feb 01 '17 at 19:37