天天看點

自動适應輸入内容寬度的TextBox控件

在ASP.NET的上面,TextBox是表單設計時最常用的控件之一。很多時候為了頁面的緊湊和美觀,我們需要适當的限制TextBox的顯示寬度,但是如果TextBox過于窄了之後,又會給使用者的填寫帶了不便,而且更麻煩的是很多時候我們并不知道使用者到底會往那個TextBox裡填多少内容。為了解決這些問題,下面給大家推薦一個可自動适應輸入内容的寬度的TextBox控件。

    本控件是從TextBox控件繼承,設計原理是使用一個agent input(type=text)來做為實際的使用者錄入的TextBox,在焦點切換的過程中完成background input和agent input的屬性同步。 

    下面的代碼完成兩個input之間的樣式和屬性同步:

自動适應輸入内容寬度的TextBox控件

function ATB_SwitchToInputAgent(input) 

    注意:不能使用style=style或for( attribute in style)的方式來指派,否這引起onpropertychange的死循環遞歸

自動适應輸入内容寬度的TextBox控件

    第二個問題是使用onpropertychange屬性來同步agent input的寬度和其内容寬度相等,代碼如下: 

自動适應輸入内容寬度的TextBox控件

function ATB_AutoIncreaseWidth(input) 

自動适應輸入内容寬度的TextBox控件

自動适應輸入内容寬度的TextBox控件

    if ( input.style.display == 'none' ) return; 

自動适應輸入内容寬度的TextBox控件

    var spanWrapper = input.parentElement; 

自動适應輸入内容寬度的TextBox控件

    var userInput = spanWrapper.firstChild; 

自動适應輸入内容寬度的TextBox控件

    userInput.value = input.value; 

自動适應輸入内容寬度的TextBox控件

    var absOffsetWidth = GetAbsoluteOffsetLeft(input); 

自動适應輸入内容寬度的TextBox控件

    var docClientWidth = window.document.body.clientWidth; 

自動适應輸入内容寬度的TextBox控件

    if ( input.scrollWidth < userInput.clientWidth ) 

自動适應輸入内容寬度的TextBox控件

    { 

自動适應輸入内容寬度的TextBox控件

        if ( absOffsetWidth + styleWidth >= docClientWidth )  

自動适應輸入内容寬度的TextBox控件

        { 

自動适應輸入内容寬度的TextBox控件

            input.style.width = docClientWidth - absOffsetWidth; 

自動适應輸入内容寬度的TextBox控件

        } 

自動适應輸入内容寬度的TextBox控件

        else 

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

            input.style.width = userInput.clientWidth+2; 

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

        return; 

自動适應輸入内容寬度的TextBox控件

    } 

自動适應輸入内容寬度的TextBox控件

    var styleWidth = parseInt(input.style.width); 

自動适應輸入内容寬度的TextBox控件

    if ( styleWidth != input.scrollWidth+2 ) 

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

            input.style.width = input.scrollWidth+2; 

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

    這裡需要注意的是當增長的agent input的最右端超出了IE的body區域時,需要停止其增長,否則使用者看不見輸入的東西了。 

    示範效果如下:

*

自動适應輸入内容寬度的TextBox控件

#region 附 AdjustableTextBox 控件源碼

自動适應輸入内容寬度的TextBox控件

using System;

自動适應輸入内容寬度的TextBox控件

using System.IO;

自動适應輸入内容寬度的TextBox控件

using System.Drawing;

自動适應輸入内容寬度的TextBox控件

using System.Text;

自動适應輸入内容寬度的TextBox控件

using System.Web.UI;

自動适應輸入内容寬度的TextBox控件

using System.Web.UI.WebControls;

自動适應輸入内容寬度的TextBox控件

using System.ComponentModel;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

namespace WebExcel.UI.WebControls

自動适應輸入内容寬度的TextBox控件

{

自動适應輸入内容寬度的TextBox控件

    /// <summary>

自動适應輸入内容寬度的TextBox控件

    /// Summary description for AdjustableTextBox.

自動适應輸入内容寬度的TextBox控件

    /// </summary>

自動适應輸入内容寬度的TextBox控件

    [DefaultProperty("Text")]

自動适應輸入内容寬度的TextBox控件

    [ToolboxData("<{0}:AdjustableTextBox runat=server></{0}:AdjustableTextBox>")]

自動适應輸入内容寬度的TextBox控件

    public class AdjustableTextBox : TextBox

自動适應輸入内容寬度的TextBox控件

    {

自動适應輸入内容寬度的TextBox控件

        public Color AgentBorderColor

自動适應輸入内容寬度的TextBox控件

        {

自動适應輸入内容寬度的TextBox控件

            get

自動适應輸入内容寬度的TextBox控件

            {

自動适應輸入内容寬度的TextBox控件

                object obj = ViewState["AgentBorderColor"];

自動适應輸入内容寬度的TextBox控件

                return obj == null ? Color.Gray : (Color)obj;

自動适應輸入内容寬度的TextBox控件

            }

自動适應輸入内容寬度的TextBox控件

            set

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                ViewState["AgentBorderColor"] = value;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

        }

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

        public bool AutoIncrease

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                object obj = ViewState["AutoIncrease"];

自動适應輸入内容寬度的TextBox控件

                return obj == null ? true : (bool)obj;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                ViewState["AutoIncrease"] = value;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

        // the property is always TextBoxMode.SingleLine.

自動适應輸入内容寬度的TextBox控件

        public override TextBoxMode TextMode

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                return base.TextMode;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                base.TextMode = value;

自動适應輸入内容寬度的TextBox控件

                if ( value != TextBoxMode.SingleLine )

自動适應輸入内容寬度的TextBox控件

                {

自動适應輸入内容寬度的TextBox控件

                    this.AutoIncrease = false;

自動适應輸入内容寬度的TextBox控件

                }

自動适應輸入内容寬度的TextBox控件

                else

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                    this.AutoIncrease = true;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

        public new Unit BorderWidth

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                if ( base.BorderWidth == Unit.Empty )

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                    base.BorderWidth = 1;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                return base.BorderWidth;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                if ( value != Unit.Empty )

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                    base.BorderWidth = value;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

        /// <summary> 

自動适應輸入内容寬度的TextBox控件

        /// Render this control to the output parameter specified.

自動适應輸入内容寬度的TextBox控件

        /// </summary>

自動适應輸入内容寬度的TextBox控件

        /// <param name="output"> The HTML writer to write out to </param>

自動适應輸入内容寬度的TextBox控件

        protected override void Render(HtmlTextWriter output)

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

            if ( this.AutoIncrease )

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                this.RegisterClientScript();

自動适應輸入内容寬度的TextBox控件

                base.Attributes["onfocus"] = "ATB_SwitchToInputAgent(this)";

自動适應輸入内容寬度的TextBox控件

                base.Attributes.CssStyle["position"] = "relative";

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                string spanWrapper = @"<span style='z-index: 1; position: relative; border: solid 0px black;'>{0}<input type='text' onblur='ATB_GetAgentValue(this)' onpropertychange='ATB_AutoIncreaseWidth(this)' style='border: solid 1px gray; position: absolute; display:none;' /></span>";

自動适應輸入内容寬度的TextBox控件

                StringBuilder sb = new StringBuilder();

自動适應輸入内容寬度的TextBox控件

                StringWriter sw = new StringWriter(sb);

自動适應輸入内容寬度的TextBox控件

                HtmlTextWriter htw = new HtmlTextWriter(sw);

自動适應輸入内容寬度的TextBox控件

                base.Render(htw);

自動适應輸入内容寬度的TextBox控件

                output.Write(string.Format(spanWrapper, sb.ToString(), ColorTranslator.ToHtml(this.AgentBorderColor)));

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

            else

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                // base.Attributes["onfocus"] = "this.height='100%'";

自動适應輸入内容寬度的TextBox控件

                base.Render(output);

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

        private void RegisterClientScript()

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

            const string COMMON_SCRIPT_KEY = "__CommonJavaScript__";

自動适應輸入内容寬度的TextBox控件

            string strCommon = @"<script language='javascript'>

自動适應輸入内容寬度的TextBox控件

            function GetAbsoluteOffsetLeft(element)

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                if ( element == null || arguments.length != 1 )

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                    return;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                var offsetLeft = element.offsetLeft;

自動适應輸入内容寬度的TextBox控件

                while( element = element.offsetParent )

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                    offsetLeft += element.offsetLeft;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                return offsetLeft;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

            </script>";

自動适應輸入内容寬度的TextBox控件

            if ( !this.Page.IsStartupScriptRegistered(COMMON_SCRIPT_KEY) )

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                this.Page.RegisterStartupScript(COMMON_SCRIPT_KEY, strCommon);

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

            const string SCRIPT_KEY = "__AdjustableTextBoxKey__";

自動适應輸入内容寬度的TextBox控件

            string strScript = @"

自動适應輸入内容寬度的TextBox控件

                <script language='javascript'>

自動适應輸入内容寬度的TextBox控件

                function ATB_SwitchToInputAgent(input)

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                    if ( input.disabled ) return;

自動适應輸入内容寬度的TextBox控件

                    var spanWrapper = input.parentElement;

自動适應輸入内容寬度的TextBox控件

                    var agentInput = spanWrapper.lastChild;

自動适應輸入内容寬度的TextBox控件

                    var userOffsetTop, userOffsetLeft;

自動适應輸入内容寬度的TextBox控件

                    with(input.style)

自動适應輸入内容寬度的TextBox控件

                    {

自動适應輸入内容寬度的TextBox控件

                        var userMarginTop = parseInt(marginTop);

自動适應輸入内容寬度的TextBox控件

                        var userMarginLeft = parseInt(marginLeft);

自動适應輸入内容寬度的TextBox控件

                        var userBorderTop = parseInt(borderTopWidth);

自動适應輸入内容寬度的TextBox控件

                        var userBorderLeft = parseInt(borderLeftWidth);

自動适應輸入内容寬度的TextBox控件

                        userMarginTop = isNaN(userMarginTop) ? 0 : userMarginTop;

自動适應輸入内容寬度的TextBox控件

                        userMarginLeft = isNaN(userMarginLeft) ? 0 : userMarginLeft;

自動适應輸入内容寬度的TextBox控件

                        userBorderTop = isNaN(userBorderTop) ? 0 : userBorderTop;

自動适應輸入内容寬度的TextBox控件

                        userBorderLeft = isNaN(userBorderLeft) ? 0 : userBorderLeft;

自動适應輸入内容寬度的TextBox控件

                        userOffsetTop = userBorderTop + userMarginTop;

自動适應輸入内容寬度的TextBox控件

                        userOffsetLeft = userBorderLeft + userMarginLeft;

自動适應輸入内容寬度的TextBox控件

                    }

自動适應輸入内容寬度的TextBox控件

                    var retouch = 0;

自動适應輸入内容寬度的TextBox控件

                    agentInput.value = input.value; // must be mdified at first

自動适應輸入内容寬度的TextBox控件

                    agentInput.style.top = userOffsetTop;

自動适應輸入内容寬度的TextBox控件

                    agentInput.style.left = userOffsetLeft-1;

自動适應輸入内容寬度的TextBox控件

                    spanWrapper.style.zIndex = 10;

自動适應輸入内容寬度的TextBox控件

                    agentInput.style.display = 'inline';

自動适應輸入内容寬度的TextBox控件

                    agentInput.style.borderWdith = input.style.borderWdith;

自動适應輸入内容寬度的TextBox控件

                    agentInput.style.borderColor = input.style.borderColor;

自動适應輸入内容寬度的TextBox控件

                    agentInput.style.backgroundColor = input.style.backgroundColor;

自動适應輸入内容寬度的TextBox控件

                    agentInput.style.color = input.style.color;

自動适應輸入内容寬度的TextBox控件

                    agentInput.style.fontFamily = input.style.fontFamily;

自動适應輸入内容寬度的TextBox控件

                    agentInput.style.fontWegith = input.style.fontWeight;

自動适應輸入内容寬度的TextBox控件

                    agentInput.style.fontSize = input.style.fontSize;

自動适應輸入内容寬度的TextBox控件

                    agentInput.style.height = input.style.height;

自動适應輸入内容寬度的TextBox控件

                    var absOffsetWidth = GetAbsoluteOffsetLeft(input);

自動适應輸入内容寬度的TextBox控件

                    var docClientWidth = window.document.body.clientWidth;

自動适應輸入内容寬度的TextBox控件

                    var styleWidth = parseInt(agentInput.style.width);

自動适應輸入内容寬度的TextBox控件

                    if ( absOffsetWidth + styleWidth >= docClientWidth ) 

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                        agentInput.style.width = docClientWidth - absOffsetWidth;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                    else

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                        agentInput.style.width = input.clientWidth+2;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                    agentInput.style.fontStyle = input.style.fontStyle;

自動适應輸入内容寬度的TextBox控件

                    try { agentInput.style.font = input.style.font } catch(exp){};

自動适應輸入内容寬度的TextBox控件

                    agentInput.style.fontVariant = input.style.fontVariant;

自動适應輸入内容寬度的TextBox控件

                    agentInput.style.zoom = input.style.zoom;

自動适應輸入内容寬度的TextBox控件

                    agentInput.readOnly = input.readOnly;

自動适應輸入内容寬度的TextBox控件

                    //agentInput.focus(); must remove!!!

自動适應輸入内容寬度的TextBox控件

                    if ( !agentInput.readOnly )

自動适應輸入内容寬度的TextBox控件

                    {        

自動适應輸入内容寬度的TextBox控件

                        agentInput.select();

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                function ATB_GetAgentValue(input)

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                    var userInput = spanWrapper.firstChild;

自動适應輸入内容寬度的TextBox控件

                    input.style.width = userInput.clientWidth+2;

自動适應輸入内容寬度的TextBox控件

                    spanWrapper.style.zIndex = 1;

自動适應輸入内容寬度的TextBox控件

                    userInput.value = input.value;

自動适應輸入内容寬度的TextBox控件

                    input.style.display = 'none';

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                function ATB_AutoIncreaseWidth(input)

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                    if ( input.style.display == 'none' ) return;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                    if ( input.scrollWidth < userInput.clientWidth )

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                        if ( absOffsetWidth + styleWidth >= docClientWidth ) 

自動适應輸入内容寬度的TextBox控件

                        {

自動适應輸入内容寬度的TextBox控件

                            input.style.width = docClientWidth - absOffsetWidth;

自動适應輸入内容寬度的TextBox控件

                        }

自動适應輸入内容寬度的TextBox控件

                        else

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                            input.style.width = userInput.clientWidth+2;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                        return;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                    var styleWidth = parseInt(input.style.width);

自動适應輸入内容寬度的TextBox控件

                    if ( styleWidth != input.scrollWidth+2 )

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                            input.style.width = input.scrollWidth+2;

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                </script>";

自動适應輸入内容寬度的TextBox控件

            if ( !this.Page.IsStartupScriptRegistered(SCRIPT_KEY) )

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

                this.Page.RegisterStartupScript(SCRIPT_KEY, strScript);

自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件
自動适應輸入内容寬度的TextBox控件

    }

自動适應輸入内容寬度的TextBox控件

}

自動适應輸入内容寬度的TextBox控件

#endregion

本文轉自部落格園鳥食軒的部落格,原文連結:http://www.cnblogs.com/birdshome/,如需轉載請自行聯系原部落客。

繼續閱讀