在运行时动态绑定到自定义业务对象
我正在开发一个 Web 表单 项目,该项目将 Sql 查询的结果加载到 数据表。
这些 DataTable 被传递到我们的前端将它们绑定到 Repeater Web 控件。
这很好用。但是,现在我们希望绑定到我们自己的自定义类而不是 DataTable
。不幸的是,我认为显而易见的答案不起作用(在我们的类上实现 IDictionary
在不为每个绑定创建具体属性的情况下,我们需要什么才能将 Eval 绑定到 Datum?显然,DataRow 不必具体实现我们绑定的每个属性。因此,Eval 似乎能够在 DataRow 上按名称查找属性值。
这是自定义类
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];
}
}
...
}
这是在 aspx.cs 文件中设置 DataSource 的位置
rptTags.DataSource = new[] { new Datum { {"Count", 1} }, new Datum { {"Count", 2 } };
这是 aspx 文件中的绑定
<asp:Repeater ID="rptTags" runat="server">
<ItemTemplate>
<%# (int)Eval("Count") >
</ItemTemplate>
</asp:Repeater>
使用上面的示例,我们收到一条错误,指出相关属性不存在,这是真的,但它也不存在于 DataRow 上。我怎样才能让它像System.Data.DataRow一样绑定?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
今天早上我以全新的眼光来到这里,花了几个小时使用 ILSpy 浏览 .Net Framework。我终于能够解决这个难题并实施一个可行的解决方案。我将列出我学到的与解决方案相关的内容,然后详细说明我的实现。
考虑到这一点,我必须采取以下步骤来创建我自己的自定义类型,我可以像 DataTable 一样动态绑定到该类型。
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.
可绑定数据源应实现
IEnumerable
或IListSource
。关于动态方面:请记住,数据绑定的部分魔力是通过反射实现的。
A bindable DataSource should implement either
IEnumerable
orIListSource
.Regarding the dynamic aspect: keep in mind that part of the magic of databinding happens using reflection.