我创建了一个CompositeDataBoundControl,我可以很好地数据绑定。 现在我想做同样的事情,但不是针对对象列表,而是针对单个对象。 原因是我希望我的同事能够简单地使用<%#Eval(“X”)%>在他们的前端代码中。
问题是CompositeDataBoundControl有一个我必须覆盖的方法,它只接受一个集合作为数据源
CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)
有没有办法为单个对象做同样的事情?
答案 0 :(得分:4)
您需要覆盖 DataSource 属性
public class SingleObjectView : CompositeDataBoundControl
{
private object dataSource;
public override object DataSource
{
get { return new List<object> { dataSource }; }
set { dataSource = value; }
}
protected override int CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)
{
SingleItem singleItem = null;
if (dataBinding)
{
var it = dataSource.GetEnumerator();
it.MoveNext();
singleItem = new SingleItem(it.Current);
}
else
{
singleItem = new SingleItem(null);
}
ItemTemplate.InstantiateIn(singleItem);
Controls.Add(singleItem);
if (dataBinding)
singleItem.DataBind();
return 1;
}
[PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(SingleItem))]
public ITemplate ItemTemplate { get; set; }
}
public class SingleItem : Control, IDataItemContainer
{
public SingleItem(object dataItem)
{
DataItem = dataItem;
}
public object DataItem { get; set; }
public int DataItemIndex
{
get { return 0; }
}
public int DisplayIndex
{
get { return 0; }
}
}
编辑以显示用法
<ctrl:SingleObjectView ID="productView" runat="server">
<ItemTemplate>
<%# Eval("ProductName") %>
<br />
<%# Eval("Price","{0:c}") %>
</ItemTemplate>
</ctrl:SingleObjectView>
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
productView.DataSource = new { ProductName="My Product", Price="10"};
productView.DataBind();
}
}
因此,DataSource接收的对象没有实现IEnumerable
,但覆盖SingleObjectView
控件的DataSource属性,确保调用CreateChildControls
。
答案 1 :(得分:2)
如何创建控件列表,添加一个对象然后调用方法?
答案 2 :(得分:0)
我使用FormView来允许模拟单个对象的实例:
protected void fvProduct_Init(object sender, EventArgs e)
{
// Load product template
fvProduct.ItemTemplate = LoadTemplate("Templates/ProductTemplate.ascx");
// Bind product to data source
fvProduct.DataSource = new[] { Product };
fvProduct.DataBind();
}
然后在ProductTemplate.ascx
你可以做这样的事情:
<h1><%# Eval("ProductName") %></h1>
<p><%# Eval("Description") %></p>
<h4><%# Eval("Price", "{0:C}")%></h4>
在你的场景中,你提到你使用的是自定义控件,但这个想法与上面的答案基本相同。您只需使用一个项创建一个枚举并绑定它。使用FormView
的原因是因为它被设计为一次只显示一个项目。