I am working on a Web Forms project that loads the results of Sql queries into DataTables.
These DataTables are passed up to the front-end where we bind them to a Repeater web control.
This works great. However, now we'd like to bind to our own custom classes instead of a DataTable
. Unfortunately, what I thought was the obvious answer didn't work (implementing IDictionary<string, object>
on our class).
What do we need to have Eval bind to Datum without creating a concrete property for every binding? Clearly DataRow doesn't have to concretely implement every property we bind. So, somehow it seems that Eval is able to look up the property values by name on DataRow.
Here is the custom class
public class Datum: IDictionary<string, object>
{
private Dictionary<string, object> _entries;
public Datum()
{
_entries = new Dictionary<string, object>();
}
public object this[string s]
{
get
{
return this._entries[s];
}
}
...
}
Here is where the DataSource is set in the aspx.cs file
rptTags.DataSource = new[] { new Datum { {"Count", 1} }, new Datum { {"Count", 2 } };
And here is the binding in the aspx file
<asp:Repeater ID="rptTags" runat="server">
<ItemTemplate>
<%# (int)Eval("Count") >
</ItemTemplate>
</asp:Repeater>
Using the above example we get an error saying that the property in question doesn't exist, which is true, but it doesn't exist on DataRow either. How can I make it bind like System.Data.DataRow?
I came in this morning with fresh eyes and spent several hours going through the .Net Framework with ILSpy. I was finally able to figure this puzzle out and implement a working solution. I'll list things I learned that are pertinent to the solution and then detail my implementation.
ICustomTypeDescriptor
interface which is what we need to implement on our class.With that in mind here are the steps I had to take to create my own custom type that I could dynamically bind to just like DataTable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With