asp.net CompositeDataBoundControl for a single object
本文关键字:single object for net CompositeDataBoundControl asp | 更新日期: 2023-09-27 18:26:22
我已经创建了一个CompositeDataBoundControl,我可以很好地对其进行数据绑定。现在我想做同样的事情,但不是针对对象列表,而是针对单个对象。原因是我希望我的同事能够简单地使用<%#Eval("X")%>在其前端代码中。
问题是CompositeDataBoundControl有一个我必须重写的方法,它只接受集合作为数据源
CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)
有没有一种方法可以对单个对象做同样的事情?
您需要覆盖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
。
创建一个控件列表,添加一个对象,然后调用该方法怎么样?
我使用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
的原因是因为它被设计为一次只显示一个项。