且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

自动适应输入内容宽度的TextBox控件

更新时间:2022-08-22 08:23:53

在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控件        if ( absOffsetWidth + styleWidth >= docClientWidth )  
自动适应输入内容宽度的TextBox控件        { 
自动适应输入内容宽度的TextBox控件            input.style.width = docClientWidth - absOffsetWidth; 
自动适应输入内容宽度的TextBox控件        } 
自动适应输入内容宽度的TextBox控件        else 
自动适应输入内容宽度的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控件            get
自动适应输入内容宽度的TextBox控件            {
自动适应输入内容宽度的TextBox控件                object obj = ViewState["AutoIncrease"];
自动适应输入内容宽度的TextBox控件                return obj == null ? true : (bool)obj;
自动适应输入内容宽度的TextBox控件            }
自动适应输入内容宽度的TextBox控件            set
自动适应输入内容宽度的TextBox控件            {
自动适应输入内容宽度的TextBox控件                ViewState["AutoIncrease"] = value;
自动适应输入内容宽度的TextBox控件            }
自动适应输入内容宽度的TextBox控件        }
自动适应输入内容宽度的TextBox控件
自动适应输入内容宽度的TextBox控件        // the property is always TextBoxMode.SingleLine.
自动适应输入内容宽度的TextBox控件
        public override TextBoxMode TextMode
自动适应输入内容宽度的TextBox控件        {
自动适应输入内容宽度的TextBox控件            get
自动适应输入内容宽度的TextBox控件            {
自动适应输入内容宽度的TextBox控件                return base.TextMode;
自动适应输入内容宽度的TextBox控件            }
自动适应输入内容宽度的TextBox控件            set
自动适应输入内容宽度的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控件            get
自动适应输入内容宽度的TextBox控件            {
自动适应输入内容宽度的TextBox控件                if ( base.BorderWidth == Unit.Empty )
自动适应输入内容宽度的TextBox控件                {
自动适应输入内容宽度的TextBox控件                    base.BorderWidth = 1;
自动适应输入内容宽度的TextBox控件                }
自动适应输入内容宽度的TextBox控件                return base.BorderWidth;
自动适应输入内容宽度的TextBox控件            }
自动适应输入内容宽度的TextBox控件            set
自动适应输入内容宽度的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控件                if ( base.BorderWidth == Unit.Empty )
自动适应输入内容宽度的TextBox控件                {
自动适应输入内容宽度的TextBox控件                    base.BorderWidth = 1;
自动适应输入内容宽度的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控件                    var spanWrapper = input.parentElement;
自动适应输入内容宽度的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控件                    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控件                        if ( absOffsetWidth + styleWidth >= docClientWidth ) 
自动适应输入内容宽度的TextBox控件                        {
自动适应输入内容宽度的TextBox控件                            input.style.width = docClientWidth - absOffsetWidth;
自动适应输入内容宽度的TextBox控件                        }
自动适应输入内容宽度的TextBox控件                        else
自动适应输入内容宽度的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/,如需转载请自行联系原博主。