简体   繁体   中英

c# enum names to filter on in a DropDownList instead of value

I have a list of enums that includes a enumeration called Default.

public enum Fruits { Default = Banana, 
                    Banana = 1, 
                    Orange = 2, 
                    Grapefruit = 3 }

I need to populate a dropdownlist that excludes the Default field.

Html.DropDownList("fruitSelector", 
                Enum.GetValues(typeof(Fruits)).Cast<Fruits>()
                    .OrderBy(o => o.GetDescription())
                    .Where(o => o != Fruits.Default)
                    .Select(o => new SelectListItem() {Text = o.GetDescription(), Value = ((int) o).ToString()}), "-- All Fruits --",
                new {@class = "form-control", @aria_describedby="sizing-addon1"})

when i try to filter on Fruits.Default it removes BOTH default and the Banana. How can i do a filter comparison where i only remove Default?

[[CORRECTION]] this enum duplicates my problem. I honestly don't understand the difference.

public enum Fruits
    {
        Default = Peaches,
        Peaches = 1,
        Bananas = 2,
        Grapefruit = 3,
        Apple = 101,
        Watermellon = 102
    }

or

public enum Fruits2
{
    Default = Mangos,
    Mangos = 1,
    Dates = 2,
    Figs = 3,
    Apples = 101,
    Limes = 102,
    Grapes = 103
}

I don't think what you're trying to do is possible as it is . The problem is your Enum structure.

public enum Fruits
{
    Default = Peaches,
    Peaches = 1,
    Bananas = 2,
    Grapefruit = 3,
    Apple = 101,
    Watermellon = 102
}

You're saying value of Default is Peaches of which value in turn is 1 . Which essentially is the same as ( B is Peaches and A is Default :

int B = 1;
int A = B;

So when we use Enum.Parse() , it treats both the same, and picks the first value. You'll understand when you look at the following scenario. Run the following code, with your current Enum:

var deflt = Enum.Parse(typeof(Fruits), Fruits.Default.ToString());
var peach = Enum.Parse(typeof(Fruits), Fruits.Peaches.ToString());
Console.WriteLine(deflt);
Console.WriteLine(peach);

The output is going to be:

Default

Default

Then change your Enum to this:

public enum Fruits
{
    Peaches = Default ,
    Default = 1,
    Bananas = 2,
    Grapefruit = 3,
    Apple = 101,
    Watermellon = 102
}

And run the above two lines of code again. Your output this time will be:

Peaches

Peaches

That is, Parse() picks the first defined Enum when there's an equality like you have.

EDIT:

The above explanation is slightly incorrect, as pointed out in the comments below by George Alexandria. Please see his explanation: You have the different output when use Peaches = Default , Default = 1, and Default = Peaches, Peaches = 1, because you invoke Enum.ToString in Console.WriteLine. If you look at the var deflt, var peach you will see that they are the same in the both cases and they are the value which name is the first by alphabetical.


But there is a workaround. From your initial code sample what I gather is you need a list of Enums, their descriptions, and their numerical values, am I correct? So, I would first just grab a list of strings excluding Default which is quite simple. Then iterate through the string list, and add to a list of your SelectListItem class objects.

var res = Enum.GetNames(typeof(Fruits))
    .Where(x => x != "Default");

List<SelectListItem> list = new List<SelectListItem>();
foreach (string fruit in res)
{
    string desc = EnumHelper<Fruits>.GetEnumDescription(fruit); // This is a utility method I use. You can get the description using your extension method.
    int val = (int)Enum.Parse(typeof(Fruits), fruit);
    list.Add(new SelectListItem { enumName = fruit, enumDesc = desc, enumVal = val });
}

And if you must have that OrderBy , after creating your SelectListItem list, sort it once again by Description .

You should compare enum values by their names, because Default and Banana are equal. So just try to retrieve names, filter them and parse them to values.

var res = Enum.GetNames(typeof(Fruits))
              .Where(o => o != nameof(Fruits.Default))
              .Select(o => Enum.Parse(typeof(Fruits), o))
              .Cast<Fruits>().ToList();

It's your full example:

Html.DropDownList("fruitSelector",
            Enum.GetNames(typeof(Fruits))
                .Where(o => o != nameof(Fruits.Default))
                .Select(o => Enum.Parse(typeof(Fruits), o)).Cast<Fruits>()
                .OrderBy(o => o.GetDescription())
                .Select(o => new SelectListItem() { Text = o.GetDescription(), Value = ((int)o).ToString() }), "-- All Fruits --",
            new { @class = "form-control", @aria_describedby = "sizing-addon1" })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM