Reputation: 247
Problem: I have an enumerated type which has description tags in the following style: [URL="http://xml.indelv.com/data-binding-enum.html"]description tag tutorial[/URL] . I have a Windows SQL Server Database from which I am pulling the data (as integers then castine to Enums) which is then being bound to a datagrid. Instead of pulling and casing the enumerated types, I would like to display the description tag associated with it in the enumerated type.
Here is the ASP -
<asp:GridView ID="StatementGrid" runat="server" AutoGenerateColumns="false" DataKeyNames="statementID" OnRowDeleting="StatementGrid_onDeleting" AllowSorting="False">
<Columns>
<asp:BoundField HeaderText="Type" SortExpression="type" DataField="TypeOfStatement" />
<asp:HyperLinkField HeaderText="Statement" DataTextField="StatementText" DataNavigateUrlFormatString="~/Gateway/Statements/View.aspx?statementID={0}" SortExpression="statement" DataNavigateUrlFields="statementID" />
<asp:HyperLinkField DataNavigateUrlFields="statementID" DataNavigateUrlFormatString="~/Gateway/Statements/Update.aspx?statementID={0}" NavigateUrl="~/Gateway/Statements/Update.aspx" HeaderText="Edit" Text="<img src='../../Images/News/news_edit.gif' alt='Edit Statement'/>" />
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:ImageButton AlternateText="Delete Statement" ID="DeleteButton" ImageUrl="~/Images/News/news_delete.gif" runat="server" CommandName="Delete" OnClientClick="javascript:return confirm('Are you sure you want to delete this statement?');" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
There are no statements to display.
</EmptyDataTemplate>
</asp:GridView>
Here is the code for the Bind -
[CODE]
private void BindData()
{
IStatementDao statementDao = DaoFactory.GetStatementDao();
List<Statement> statements;
if (Page.Request.RawUrl.Contains("Gateway"))
{
statements = statementDao.GetAll();
StatementGrid.HeaderStyle.CssClass = "GatewayGridHeader";
StatementGrid.AlternatingRowStyle.CssClass = "GatewayGridAlternatingRow";
}
else
{
// This should never be reached but it keeps the compiler happy!!
statements = statementDao.GetAll();
}
StatementGrid.DataSource = statements;
StatementGrid.DataBind();
DisplayTypeDescriptors();
}
[/CODE]
Here is the enumerated class -
[CODE]
public enum TypeOfStatement
{
[EnumDescription("Dress Code")] DressCode = 1,
[EnumDescription("Lunch Time")] LunchTime = 2,
[EnumDescription("Footwarez")] Footware = 3,
[EnumDescription("achtung")] Warning = 4,
[EnumDescription("Banarna")] Banana = 5,
[EnumDescription("Apfel")] Apple = 6
};c#
[/CODE]
Its obvious that one could write an extensive method do do what i want, but is there a neater way?
Upvotes: 2
Views: 5841
Reputation: 36438
Wrap them up on the fly and subtly change your handling of the SelectedItem (or whatever you are using)
My example uses the already present Description attribute.
public class DescriptiveEnum<T> where T: struct
{
private static readonly Dictionary<T,string> descriptions
= new Dictionary<T,string>();
static DescriptiveEnum()
{
foreach (FieldInfo field in
typeof(T).GetFields(BindingFlags.Static
| BindingFlags.GetField | BindingFlags.Public))
{
descriptions.Add((T)field.GetRawConstantValue(),
LookupName(field));
}
}
public readonly T Value;
public DescriptiveEnum(T value)
{
this.Value = value;
}
public override string ToString()
{
string s;
if (!descriptions.TryGetValue(this.Value, out s))
{
// fall back for non declared fields
s = this.Value.ToString();
descriptions[this.Value] = s;
}
return s;
}
private static string LookupName(FieldInfo field)
{
object[] all = field.GetCustomAttributes(
typeof(DescriptionAttribute), false);
if (all.Length == 0)
return field.Name; // fall back
else
return ((DescriptionAttribute)all[0])
.Description; // only one needed
}
public static BindingList<DescriptiveEnum<T>> Make(
IEnumerable<T> source)
{
var list = new BindingList<DescriptiveEnum<T>>();
foreach (var x in source)
list.Add(new DescriptiveEnum<T>(x));
return list;
}
}
example usage:
public enum Foo
{
[Description("flibble")]
Bar,
[Description("wobble")]
Baz,
// none present, will use the name
Bat
}
Form f = new Form();
f.Controls.Add(new ListBox()
{
Dock = DockStyle.Fill,
DataSource = DescriptiveEnum<Foo>.Make(
new Foo[] { Foo.Bar, Foo.Baz, Foo.Bat }),
});
Application.Run(f);
Upvotes: 2