mostlylucid

STATIC ARCHIVE of mostlylucid.co.uk of old
posts - 892, comments - 676, trackbacks - 11

My Links

News

follow me on twitter!

Archives

Post Categories

Misc. Coding

Cool little thing I keep losing...ObjectRepeater

This is a brilliant little server control from Rob van der Veer (found here) – which I’ve found lots of uses for but keep having to spend time tracking it down…so here it is, mainly for me but partly for you too  

///

    /// A templated databound repeater that dynamically determines which

    /// template to use based on the class of the object in the collection.

    ///

    [ParseChildren(false)]

    [ControlBuilder(typeof(ObjectRepeaterControlBuilder))]

    public class ObjectRepeater : System.Web.UI.Control, System.Web.UI.INamingContainer, IParserAccessor

    {

        private Hashtable _templates = new Hashtable();

        private string _defaultTemplateName = null;

        private IEnumerable _dataSource;

 

        public ObjectRepeaterDetermineTemplateDelegate DetermineTemplate;

        public event RepeaterItemEventHandler ItemCreated;

        public event RepeaterItemEventHandler ItemDataBound;

        public event RepeaterCommandEventHandler ItemCommand;

 

        #region Properties

 

        public string DefaultTemplate

        {

            get

            {

                return _defaultTemplateName;

            }

            set

            {

                _defaultTemplateName = value;

            }

        }

 

        public virtual IEnumerable DataSource

        {

            get

            {

                return _dataSource;

            }

            set

            {

                _dataSource = value;

            }

        }

 

        public ControlCollection Items

        {

            get

            {

                return this.Controls;

            }

        }

 

        #endregion

 

        #region Methods

 

        public void OnItemDataBound(RepeaterItemEventArgs e)

        {

            if(this.ItemDataBound != null)

                this.ItemDataBound(this, e);

        }

 

        public void OnItemCreated(RepeaterItemEventArgs e)

        {

            if(this.ItemCreated != null)

                this.ItemCreated(this, e);

        }

 

        public void OnItemCommand(RepeaterCommandEventArgs e)

        {

            if(this.ItemCommand != null)

                this.ItemCommand(this, e);

        }

 

        public override void DataBind()

        {

            // Controls with a data-source property perform their

            // custom data binding by overriding DataBind to

            // evaluate any data-binding expressions on the control   

            // itself.

            base.OnDataBinding(EventArgs.Empty);

 

            // Reset the control's state.

            Controls.Clear();

            ClearChildViewState();

 

            // Create the control hierarchy using the data source.

            CreateControlHierarchy(true);

            ChildControlsCreated = true;

 

            TrackViewState();

 

        }

 

        protected override void CreateChildControls()

        {

            Controls.Clear();

 

            if (ViewState["ItemCount"] != null)

            {

                // Create the control hierarchy using the view state,

                // not the data source.

                CreateControlHierarchy(false);

            }

        }

 

        ///

        ///

        ///

        /// True to create the hierarchy from the DataSource, False to create it from the ViewState.

        private void CreateControlHierarchy(bool useDataSource)

        {

            IEnumerable dataSource = null;

            int count = -1;

 

            if (useDataSource == false)

            {

                // ViewState must have a non-null value for ItemCount because this is checked

                //  by CreateChildControls.

                count = (int)ViewState["ItemCount"];

                if (count != -1)

                {

                    dataSource = new DummyDataSource(count);

                }

            }

            else

            {

                dataSource = this._dataSource;

            }

 

            if (dataSource != null)

            {

                int index = 0;

                count = 0;

                foreach (object dataItem in dataSource)

                {

                    CreateItem(index, ListItemType.Item, useDataSource, dataItem);

 

                    count++;

                    index++;

                }

            }

 

            if (useDataSource)

            {

                // Save the number of items contained for use in round trips.

                ViewState["ItemCount"] = ((dataSource != null) ? count : -1);

            }

        }

 

        private RepeaterItem CreateItem(int itemIndex, ListItemType itemType, bool dataBind, object dataItem)

        {

            RepeaterItem item = new RepeaterItem(itemIndex, itemType);

 

            RepeaterItemEventArgs e = new RepeaterItemEventArgs(item);

 

            //decide which template to use.

            string templateName = null;

 

            if(dataBind)

            {

                if(DetermineTemplate != null)

                {

                    templateName = this.DetermineTemplate(this, dataItem);

                    ViewState["templateName" + itemIndex.ToString()] = templateName;

                }

            }

            else

            {

                //determine template to use from viewState;

                templateName = (string)ViewState["templateName" + itemIndex.ToString()];

            }

 

            if(templateName == null)

                templateName = this.DefaultTemplate;

            ObjectTemplate dynamicTemplate = (ObjectTemplate)_templates[templateName];

 

 

            //Must exist.

            dynamicTemplate.ItemTemplate.InstantiateIn(item);

 

            if (dataBind)

            {

                item.DataItem = dataItem;

            }

            OnItemCreated(e);

            this.Controls.Add(item);

 

            if (dataBind)

            {

                item.DataBind();

                OnItemDataBound(e);

 

                item.DataItem = null;

            }

 

            return item;

        }

 

        protected override bool OnBubbleEvent(object source, EventArgs e)

        {

            // Handle events raised by children by overriding OnBubbleEvent.

 

            bool handled = false;

 

            if (e is CommandEventArgs)

            {

                RepeaterCommandEventArgs ce = (RepeaterCommandEventArgs)e;

 

                OnItemCommand(ce);

                handled = true;

            }

 

            return handled;

        }

 

 

        ///

        /// This member overrides Control.AddParsedSubObject.

        /// it catches the contents of each item.

        ///

        protected override void AddParsedSubObject(object obj)

        {

            if(obj is ObjectTemplate)

            {   

                ObjectTemplate template = (ObjectTemplate)obj;

                _templates.Add(template.Name, template);

                return;

            }

            else

            {

                if(!(obj is LiteralControl))

                    throw new Exception("ObjectRepeater can only have children of type 'ObjectTemplate'");

            }

            base.AddParsedSubObject(obj);

        }   

 

        #endregion

    }   

 

    public delegate string ObjectRepeaterDetermineTemplateDelegate(object sender, object dataItem);

 

    #region Control Builder

    ///

    /// Interacts with the parser to build a PanelBar control.

    ///

    public class ObjectRepeaterControlBuilder : ControlBuilder

    {

        ///

        /// This member overrides ControlBuilder.GetChildControlType.

        ///

        public override Type GetChildControlType(string tagName, IDictionary attributes)

        {

            // check is the tag is an TabStripPanelItem tag

            if (tagName.ToLower().IndexOf("objecttemplate") >= 0)

            {

                System.Diagnostics.Trace.WriteLine(tagName);

 

                // yes, so return TabStripPanelItem type

                return typeof(ObjectTemplate);

 

            }

            return null;

        }

 

        public override void AppendLiteralString(string s)

        {

            //empty implementation to drop literal content.

            System.Diagnostics.Trace.WriteLine(s);

        }

 

    }

    #endregion

 

    [ParseChildren(true)]

    public class ObjectTemplate : Control

    {

        private string _name;

        private ITemplate _itemTemplate;

 

        [TemplateContainer(typeof(RepeaterItem))]

        public ITemplate ItemTemplate

        {

            get { return _itemTemplate; }

            set { _itemTemplate = value; }

        }

 

        public string Name

        {

            get { return _name; }

            set { _name = value; }

        }

    }

    internal sealed class DummyDataSource : ICollection

    {

        private int dataItemCount;

        public DummyDataSource(int dataItemCount)

        {

            this.dataItemCount = dataItemCount;

        }

        public int Count

        {

            get

            {

                return dataItemCount;

            }

        }

        public bool IsReadOnly

        {

            get

            {

                return false;

            }

        }

        public bool IsSynchronized

        {

            get

            {

                return false;

            }

        }

        public object SyncRoot

        {

            get

            {

                return this;

            }

        }

        public void CopyTo(Array array, int index)

        {

            for (IEnumerator e = this.GetEnumerator(); e.MoveNext();)

                array.SetValue(e.Current, index++);

        }

        public IEnumerator GetEnumerator()

        {

            return new BasicDataSourceEnumerator(dataItemCount);

        }

 

        private class BasicDataSourceEnumerator : IEnumerator

        {

            private int count;

            private int index;

            public BasicDataSourceEnumerator(int count)

            {

                this.count = count;

                this.index = -1;

            }

            public object Current

            {

                get

                {

                    return null;

                }

            }

            public bool MoveNext()

            {

                index++;

                return index < count;

            }

            public void Reset()

            {

                this.index = -1;

            }

        }

    }

Print | posted on Tuesday, May 24, 2005 3:42 AM | Filed Under [ Code Snippets ]

Feedback

# re: Cool little thing I keep losing...ObjectRepeater

I believe that any DataLayer must be a simple code block, that they allow operations against DB. That code block would not have to know on the Business Entities. Single to specialize it is to execute the operations (Store Procedures and SQL Sentences) against the engine DB (SQL, Oracle, DB2, etc.), with which this setting. Finally, I invite to you to download the DataLayer.Primitives Public Version. This is very cool Data Layer :) DataLayer.Primitives - Readme! http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=1389 Cheers, Javier Luna http://guydotnetxmlwebservices.blogspot.com/
5/24/2005 8:40 PM | Javier Luna

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 6 and 8 and type the answer here:

Powered by: