Pages

Tuesday, November 23, 2010

Create a custom panel that can expand/contract and that you can nest other controls in

Create a custom panel that can expand/contract and that you can nest other controls in

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Text;
using System.IO;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web;

namespace CustomWebControls
{
    [ToolboxData("<{0}:basePanel runat=server>")]
    [Designer("System.Web.UI.Design.ReadWriteControlDesigner, System.Design")]
    [PersistChildren(true)]
    [ParseChildren(false)]
    ///

    /// Summary description for basePanel.
    /// This control creates a type of panel that has a header and footer bar.
    ///
    /// Copywrite type stuff. Please use where you want but leave my tags on here. Created by Chris Davey www.chemlock.co.uk
    ///

    ///
    public class basePanel : WebControl, INamingContainer
    {

        #region Attributes

        private Label lblTitle;
        private HtmlGenericControl bodyDiv;
        protected bool embedded;

        protected HtmlGenericControl titleDiv;
        protected Panel mainDiv;
        protected HtmlGenericControl footerDiv;

        protected ImageButton ibtnMinMax;
        protected ImageButton ibtnClose;

        protected ImageButton ibtnSave;
        protected ImageButton ibtnCancel;

        public event EventHandler SaveEvent;
        public event EventHandler CancelEvent;

        private string imgExpand;
        private string imgContract;

        protected bool create;


        #endregion Attributes

        #region Properties

        [Bindable(true)]
        [Category("Expand Butotn")]
        [DefaultValue("")]
        [Editor(typeof(ImageUrlEditor), typeof(UITypeEditor))]
        public string ImageURLExpand
        {
            get { return imgExpand; }
            set { imgExpand = value; }
        }

        [Bindable(true)]
        [Category("Contract Button")]
        [DefaultValue("")]
        [Editor(typeof(ImageUrlEditor), typeof(UITypeEditor))]
        public string ImageURLContract
        {
            get { return imgContract; }
            set { imgContract = value; }
        }

        [Bindable(true)]
        [Category("Close Button")]
        [DefaultValue("")]
        [Editor(typeof(ImageUrlEditor), typeof(UITypeEditor))]
        public string ImageURLClose
        {
            get { return this.ibtnClose.ImageUrl; }
            set { this.ibtnClose.ImageUrl = value; }
        }

        [Bindable(true)]
        [Category("Save Button")]
        [DefaultValue("")]
        [Editor(typeof(ImageUrlEditor), typeof(UITypeEditor))]
        public string ImageURLSave
        {
            get { return this.ibtnSave.ImageUrl; }
            set { this.ibtnSave.ImageUrl = value; }
        }

        [Bindable(true)]
        [Category("Cancel Button")]
        [DefaultValue("")]
        [Editor(typeof(ImageUrlEditor), typeof(UITypeEditor))]
        public string ImageURLCancel
        {
            get { return this.ibtnCancel.ImageUrl; }
            set { this.ibtnCancel.ImageUrl = value; }
        }

        ///

        /// The title that will appear in the control header
        ///

        public string Title
        {
            get { return this.lblTitle.Text; }
            set { this.lblTitle.Text = value; }
        }

        ///

        /// Read Only value. Set to true of the main control window is maximised
        ///

        public bool Maximized
        {
            get { return this.mainDiv.Visible; }
        }

        ///

        /// Set or get the body css class
        ///

        public string CssClassBody
        {
            get { return this.bodyDiv.Attributes["class"]; }
            set { this.bodyDiv.Attributes.Add("class", value); }
        }

        ///

        /// Set or get the visibility of the Close button
        ///

        public bool ShowCloseButton
        {
            get { return this.ibtnClose.Visible; }
            set { this.ibtnClose.Visible = value; }
        }

        ///

        /// Set or get the visibility of the Min/Max button
        ///

        public bool ShowMinMaxButton
        {
            get { return this.ibtnMinMax.Visible; }
            set { this.ibtnMinMax.Visible = value; }
        }

        ///

        ///
        ///

        public bool ShowFooter
        {
            get { return this.footerDiv.Visible; }
            set { this.footerDiv.Visible = value; }
        }

        ///

        ///
        ///

        public bool ShowHeader
        {
            get { return this.titleDiv.Visible; }
            set { this.titleDiv.Visible = value; }
        }

        ///

        ///
        ///

        public string CssClassMain
        {
            get { return this.mainDiv.CssClass; }
            set { this.mainDiv.CssClass = value; }
        }

        ///

        /// Get or set wether the control is embedded in another control (Does not show header and footer)
        ///

        public bool Embedded
        {
            get { return this.embedded; }
            set { this.embedded = value; }
        }

        #endregion Properties

        #region Constructors

        public basePanel()
        {
            //Create control set now so that properties can be used directly on them
            this.EnsureChildControls();
            this.CssClassBody = "DetailControl";
        }

        #endregion Constructors

        #region Override Methods

        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            if (HasControls())
            {

                //open a temp stream to render first two controls into (base control and custome control)
                System.IO.MemoryStream memstr = new System.IO.MemoryStream();
                System.IO.StreamWriter stream = new System.IO.StreamWriter(memstr);
                HtmlTextWriter wt = new HtmlTextWriter(stream);
                if (this.Controls.Count > 1)
                {
                    //render first 2 controls to stream
                    for (int i = 0; i < 2; i++)
                    {

                        this.Controls[i].RenderControl(wt);
                        wt.Flush();

                    }
                }
                else
                {
                    base.Render(wt);
                    wt.Flush();
                }

                    //set to start of stream
                    memstr.Seek(0, System.IO.SeekOrigin.Begin);

                    //read back the html from memory
                    System.IO.StreamReader rd = new System.IO.StreamReader(memstr);
                    char[] bytes = new char[memstr.Length];
                    rd.ReadBlock(bytes, 0, (int)memstr.Length);

                    //create string builder of the correct length
                    System.Text.StringBuilder sb = new System.Text.StringBuilder();
                    sb.EnsureCapacity((int)memstr.Length);

                    //post the bytes to the string builder
                    sb.Append(bytes);

                    //close everything
                    memstr.Close();
                    stream.Close();
                    rd.Close();
                    wt.Close();
                    if (this.Controls.Count > 2)
                    {
                        //open a temp stream to render any controls added in the IDE
                        memstr = new System.IO.MemoryStream();
                        stream = new System.IO.StreamWriter(memstr);
                        wt = new HtmlTextWriter(stream);

                        //render all other controls added during IDE
                        for (int i = 2; i < Controls.Count; i++)
                        {

                            this.Controls[i].RenderControl(wt);
                            wt.Flush();

                        }

                        //set to start of stream
                        memstr.Seek(0, System.IO.SeekOrigin.Begin);

                        //read back the html from memory
                        rd = new System.IO.StreamReader(memstr);
                        bytes = new char[memstr.Length];
                        rd.ReadBlock(bytes, 0, (int)memstr.Length);

                        //create string builder of the correct length
                        System.Text.StringBuilder sbChild = new System.Text.StringBuilder();
                        sbChild.EnsureCapacity((int)memstr.Length);

                        //post the bytes to the string builder
                        sbChild.Append(bytes);

                        //close everything
                        memstr.Close();
                        stream.Close();
                        rd.Close();
                        wt.Close();

                        //find main div and add all IDE time controls into div statement
                        sb.Replace("
", "
" + sbChild.ToString());
                    }

                    //write the html string
                    writer.WriteLine(sb.ToString());
                }
        

        }

        protected override void CreateChildControls()
        {
            if (!this.ChildControlsCreated)
            {
                this.Controls.Clear();

                base.CreateChildControls();

                this.bodyDiv = new HtmlGenericControl("div");
                this.Controls.Add(this.bodyDiv);

                this.titleDiv = new HtmlGenericControl("div");
                this.titleDiv.Attributes.Add("class", "titleDiv");
                this.bodyDiv.Controls.Add(this.titleDiv);

                this.lblTitle = new Label();
                this.lblTitle.CssClass = "titlelbl";

                this.titleDiv.Controls.Add(this.lblTitle);

                HtmlGenericControl oDivHeadBtns = new HtmlGenericControl("div");
                oDivHeadBtns.Style.Add("float", "right");
                oDivHeadBtns.Style.Add("clear", "right");
                this.titleDiv.Controls.Add(oDivHeadBtns);

                this.ibtnMinMax = new ImageButton();
                this.ibtnMinMax.CssClass = "minmaxbtn";
                this.ibtnMinMax.Click += new ImageClickEventHandler(ibtnMinMax_Click);
                oDivHeadBtns.Controls.Add(this.ibtnMinMax);

                this.ibtnClose = new ImageButton();
                this.ibtnClose.CssClass = "closebtn";
                this.ibtnClose.Click += new ImageClickEventHandler(ibtnClose_Click);
                oDivHeadBtns.Controls.Add(this.ibtnClose);

                this.mainDiv = new Panel();
                this.mainDiv.Attributes.Add("class", "mainDiv");
                this.mainDiv.Visible = true;

                this.bodyDiv.Controls.Add(this.mainDiv);

                this.footerDiv = new HtmlGenericControl("div");
                this.footerDiv.Attributes.Add("class", "footerDiv");
                this.bodyDiv.Controls.Add(this.footerDiv);

                this.ibtnSave = new ImageButton();
                this.ibtnSave.CssClass = "footerbutton";
                this.ibtnSave.Click += new ImageClickEventHandler(ibtnSave_Click);
                this.footerDiv.Controls.Add(this.ibtnSave);

                this.ibtnCancel = new ImageButton();
                this.ibtnCancel.CssClass = "footerbutton";
                this.ibtnCancel.Click += new ImageClickEventHandler(ibtnCancel_Click);
                this.footerDiv.Controls.Add(this.ibtnCancel);

            }
        }

        ///

        /// Render all panels etc as DIV not SPAN
        ///

        ///

        public override void RenderBeginTag(System.Web.UI.HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
            writer.RenderBeginTag(HtmlTextWriterTag.Div);
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            //Show the correct image for the expand/contract button
            if (this.mainDiv.Visible)
            {
                this.ibtnMinMax.ImageUrl = this.imgContract;
            }
            else
            {
                this.ibtnMinMax.ImageUrl = this.imgExpand;
            }

            //If control is in embedded mode don't show header or footer
            if (this.embedded)
            {
                this.CssClassBody = "EmbeddedControl";
                this.ShowHeader = false;
                this.ShowFooter = false;
            }

        }

        #endregion Override Methods

        #region Public Methods

        ///

        /// Allows the status of the main div to be switched between expanded and contracted
        ///

        public void ToogleVisible()
        {
            this.mainDiv.Visible = !this.mainDiv.Visible;
            this.footerDiv.Visible = this.mainDiv.Visible;
        }

        #endregion Public Methods

        #region Events

        private void ibtnMinMax_Click(object sender, ImageClickEventArgs e)
        {
            this.ToogleVisible();
        }


        private void ibtnClose_Click(object sender, ImageClickEventArgs e)
        {
            this.Visible = false;
        }


        private void ibtnCancel_Click(object sender, ImageClickEventArgs e)
        {
            //Fire CancelEvent if there is a anything listening for it
            if (CancelEvent != null)
            {
                CancelEvent(this, e);
            }
        }


        private void ibtnSave_Click(object sender, ImageClickEventArgs e)
        {
            //Fire SaveEvent if there is a anything listening for it
            if (SaveEvent != null)
            {
                SaveEvent(this, e);
            }
        }

        #endregion Events
    }
}




No comments: