Search code examples
gridviewenumsboundfield

Pass enum to method to be used as enum and type


I'm trying to pass an Enum into a method that will create columns for a gridview. I can pass the Enum as Enum passEnum OR Type enumType, and either works, just not together. What I mean is if I pass it as a type the Enum.GetNames() method accepts it, and if I pass it as an enum, the StringEnum.GetString() method accepts it. But I can't pass one and have them both accept it and I can't pass them separately (enum and type) and have both accept it. The method that AMOST works:

public static void AddColumnsToGridView(GridView gv, Enum passEnum, Type enumType)
{
    BoundField bf = new BoundField();
    int c = 0;
    foreach (string item in Enum.GetNames(enumType))
    {
        bf = new BoundField();
        bf.HeaderText = StringEnum.GetString((passEnum)c);
        bf.DataField = item;
        bf.ItemStyle.CssClass = "siteFont leftPaddingThree";
        bf.SortExpression = item;
        gv.Columns.Add(bf);
        c++;
    }
}

I get a red squiggle line under passEnum that says: "The type or namespace 'passEnum' cannot be found... etc". For some reason I can get this to work outside of a method like this:

BoundField bf = new BoundField();
int c = 0;
foreach (string item in Enum.GetNames(typeof(PatientRX)))
{
    bf = new BoundField();
    bf.HeaderText = StringEnum.GetString((PatientRX)c);
    bf.DataField = item;
    bf.ItemStyle.CssClass = "siteFont leftPaddingThree";
    bf.SortExpression = item;
    gvRX.Columns.Add(bf);
    c++;
}

The StringEnum.GetString() method gets a string value attached to the enum. It requires an enum to be passed to it. How can I get this to work in a method?


Solution

  • I worked around the problem by writing a new method for the StringEnum class that returns a list of string values for the enum instead of trying to pull each string indivually... like this:

           public static void AddColumnsToGridView(GridView gv, Type enumType)
           {
               gv.Columns.Clear();
               List<string> headers = StringEnum.GetStringValueList(enumType);
               BoundField bf = new BoundField();
               int c = 0;
               foreach (string item in Enum.GetNames(enumType))
               {
                  bf = new BoundField();
                  bf.HeaderText = headers[c];
                  bf.DataField = item;
                  bf.ItemStyle.CssClass = "siteFont leftPaddingThree";
                  bf.SortExpression = item;
                  gv.Columns.Add(bf);
                  c++;
                }
            }
    

    I would prefer using the generics, as Mike has posted... but there is still an issue with the line:

    bf.HeaderText = StringEnum.GetString((TEnum)c);
    

    The method that it calls needs an Enum and "enumType" as written in Mike's code is not considered an Enum apparently because I get an error "cannot convert from TEnum to System.Enum, here is the method it calls:

            public static string GetString(Enum value)
            {
                string output = null;
                Type type = value.GetType();
    
                if (_stringValues.ContainsKey(value))
                    output = (_stringValues[value] as StringValueAttribute).Value;
                else
                {
                    //Look for our 'StringValueAttribute' in the field's custom attributes
                    FieldInfo fi = type.GetField(value.ToString());
                    StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
                    if (attrs.Length > 0)
                    {
                        _stringValues.Add(value, attrs[0]);
                        output = attrs[0].Value;
                    }
                }
                return output;
            }
    

    I did not write the method above (or the StringEnum class)... but here is the method that I added to get the list of enum strings:

            public static List<string> GetStringValueList(Type enumType)
            {
                List<string> values = new List<string>();
                //Look for our string value associated with fields in this enum
                foreach (FieldInfo fi in enumType.GetFields())
                {
                    //Check for our custom attribute
                    var stringValueAttributes = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
                    if (stringValueAttributes.Length > 0)
                    {
                        values.Add(stringValueAttributes[0].Value);
                    }
                }
                return values;
            }
    

    If anyone knows a way that is like Mike's (that uses generics) that I can get this done I'd appreciate it. It is all a matter of learning and knowledge now because I've already implemented the solution that I have above, but I would still like to know how to do this in a truly generic way... thanks!