CodersAdvocate

I work hard, so you don't have to

Bindable Textbox List

 

Bindable objects are a god send for the .net developers of the world. It reduces the need for looping manualy through objects. There is one type of bindable list missing though.

Here is the source code for a bindable text box list. You can customise it away, and make it work how you want. But i'm sure you will find good use for it. I know i did!

//------------------------------------------------------------------------------------------------- 
// <copyright file="TexboxList.cs" company="CodersAdvocate">
// Copyright (c) .  All rights reserved.
// </copyright>
//-------------------------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace Controls
{
    /// <summary>
    /// TexboxList generic control
    /// </summary>
    public class TexboxList : DataBoundControl
    {
        /// <summary>
        /// private field
        /// </summary>
        private IEnumerable dataSource;

        /// <summary>
        /// Gets or sets the data text field.
        /// </summary>
        /// <value>The data text field.</value>
        public string DataDescriptionField { get; set; }

        /// <summary>
        /// Gets or sets the data text field.
        /// </summary>
        /// <value>The data text field.</value>
        public string DataTextField { get; set; }

        /// <summary>
        /// Gets or sets the data ID field.
        /// </summary>
        /// <value>The data ID field.</value>
        public string DataIDField { get; set; }

        /// <summary>
        /// Gets or sets the data identifier field.
        /// </summary>
        /// <value>The data identifier field.</value>
        public string DataIdentifierField { get; set; }

        /// <summary>
        /// Gets or sets the object from which the data-bound control retrieves its list of data items.
        /// </summary>
        /// <value></value>
        /// <returns>
        /// An object that represents the data source from which the data-bound control retrieves its data. The default is null.
        /// </returns>
        [Category("Data"), DefaultValue(""), Description("type IEnumerable only")]
        public new virtual IEnumerable DataSource
        {
            get
            {
                return dataSource;
            }

            set
            {
                if ((value == null) || (value is IEnumerable))
                {
                    dataSource = value;
                }
                else
                {
                    throw new ArgumentException();
                }
            }
        }

        /// <summary>
        /// Binds a data source to the invoked server control and all its child controls.
        /// </summary>
        public override void DataBind() 
        {
            base.OnDataBinding(EventArgs.Empty);
            Controls.Clear();
            ClearChildViewState();
            TrackViewState();
            CreateMyControlHeirarchy(false);
            ChildControlsCreated = true;
        }

        /// <summary>
        /// Gets the data source.
        /// </summary>
        /// <returns>returns the IEnumerable interface</returns>
        protected new virtual IEnumerable GetDataSource()
        {
            if (dataSource == null)
            {
                return null;
            }

            IEnumerable resolvedDataSource = dataSource;

            return resolvedDataSource;
        }

        /// <summary>
        /// Creates my control heirarchy.
        /// </summary>
        /// <param name="useViewState">if set to <c>true</c> [use view state].</param>
        protected virtual void CreateMyControlHeirarchy(bool useViewState)
        {
            IEnumerable resolvedDataSource;
            if (useViewState)
            {
                if (ViewState["ControlCount"] != null)
                {
                    resolvedDataSource = new object[(int)ViewState["ControlCount"]];
                }
                else
                {
                    throw new Exception("Unable to retrieve expected data from ViewState");
                }
            }
            else
            {
                resolvedDataSource = GetDataSource();
            }

            if (resolvedDataSource != null)
            {
                int i = 0;
                foreach (object dataItem in resolvedDataSource)
                {
                    if (!useViewState)
                    {
                        Literal description = new Literal();
                        TextBox textbox = new TextBox();
                        var p = new HtmlGenericControl("p");
                        textbox.ID = "TextboxList_" + dataItem.GetType().GetProperty(DataIdentifierField).GetValue(dataItem, null).ToString()
                            + "_" + dataItem.GetType().GetProperty(DataIDField).GetValue(dataItem, null).ToString();
                        textbox.Text = DataTextField == null ? string.Empty :
                            dataItem.GetType().GetProperty(DataTextField).GetValue(dataItem, null).ToString();
                        description.Text = dataItem.GetType().GetProperty(DataDescriptionField).GetValue(dataItem, null).ToString();
                        p.Controls.Add(textbox);
                        p.Controls.Add(description);
                        i++;
                        Controls.Add(p);
                    }
                }

                ViewState["ControlCount"] = i;
            }
        }

        /// <summary>
        /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation
        /// to create any child controls they contain in preparation for posting back or rendering.
        /// </summary>
        protected override void CreateChildControls()
        {
            Controls.Clear();

            if (ViewState["ControlCount"] != null)
            {
                CreateMyControlHeirarchy(true);
            }
        }

        /// <summary>
        /// Renders the contents of the control to the specified writer. This method is used primarily by control developers.
        /// </summary>
        /// <param name="writer">A <see cref="T:System.Web.UI.HtmlTextWriter"/> that represents the output
        /// stream to render HTML content on the client.</param>
        protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.Write("<div class=\"CodersAdvocate_TextBoxList\">");
            foreach (Control control in Controls)
            {
                control.RenderControl(writer);
            }
            writer.Write("</div>");
        }
    }
}

I've got to give a shout out to the good people at tohtml.com for the syntax highlighting tool they have.

Copyright 2011 CodersAdvocate ©