You need to override the DataSource property.
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; } } }
edit to show usage
<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(); } }
So, the DataSource receives an object that does not implement IEnumerable
, but overriding the DataSource property of the SingleObjectView
control, ensures that CreateChildControls
is called.
source share