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 i开发者_StackOverflown a method?
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!
It looks like you're trying to write a generic method there, without actually using generics, try something like this:
public static void AddColumnsToGridView<TEnum>(GridView gv)
{
Type enumType = typeof(TEnum);
BoundField bf = new BoundField();
int c = 0;
foreach (string item in Enum.GetNames(enumType))
{
bf = new BoundField();
bf.HeaderText = StringEnum.GetString((Enum)c);
bf.DataField = item;
bf.ItemStyle.CssClass = "siteFont leftPaddingThree";
bf.SortExpression = item;
gv.Columns.Add(bf);
c++;
}
}
It's not really how I'd go about doing it from scratch, but it should work.
edit: Sorry, I forgot to show an example of calling that, which would look like this:
AddColumnsToGridView<MyEnumType>(gridView);
edit 2: I mentioned in the comment below that you'll have problems if the enum doesn't start at 0 or misses out values. You might want to try this instead:
public static void AddColumnsToGridView(GridView gv, Type enumType)
{
Array values = Enum.GetValues(enumType)
string[] names= Enum.GetNames(enumType)
BoundField bf = new BoundField();
for (int i = 0; i < names.Length; i++)
{
bf = new BoundField();
bf.HeaderText = StringEnum.GetString((Enum)values.GetValue(i));
bf.DataField = names[i];
bf.ItemStyle.CssClass = "siteFont leftPaddingThree";
bf.SortExpression = names[i];
gv.Columns.Add(bf);
}
}
Note that this is no longer a generic method, as it doesn't need to be (It's better this way - you won't get multiple versions of the method JITted at runtime for each enum type). Just call it like this:
AddColumnsToGridView(gridView, typeof(MyEnum));
I obviously don't have the code that you have for StringEnum, so I haven't compiled this up myself, but I think it should be fine. Let me know if it's still a problem.
精彩评论