Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asp.net CompositeDataBoundControl for a single object

Tags:

c#

asp.net

I have created a CompositeDataBoundControl that i can databind perfectly well. Now i want to do the same thing, but not for a list of objects, but for a single object. Reasons is that i want my colleagues to have the ability to simply use the <%# Eval("X") %> in their front end code.

The problem is that the CompositeDataBoundControl has a method that i have to override, which only accepts a collection as a datasource

CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)

Is there a way to do the same thing for a single object?

like image 882
Tys Avatar asked Mar 02 '12 14:03

Tys


2 Answers

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 the 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 which doesn't implement IEnumerable, but overriding the DataSource property of the SingleObjectView control, ensures that CreateChildControls is called.

like image 187
Adrian Iftode Avatar answered Oct 21 '22 16:10

Adrian Iftode


What about create a list of control, add one single object and then call the method?

like image 23
AngeloBad Avatar answered Oct 21 '22 14:10

AngeloBad