在ASP.NET的上面,TextBox是表单设计时最常用的控件之一。很多时候为了页面的紧凑和美观,我们需要适当的限制TextBox的显示宽度,但是如果TextBox过于窄了之后,又会给用户的填写带了不便,而且更麻烦的是很多时候我们并不知道用户到底会往那个TextBox里填多少内容。为了解决这些问题,下面给大家推荐一个可自动适应输入内容的宽度的TextBox控件。
本控件是从TextBox控件继承,设计原理是使用一个agent input(type=text)来做为实际的用户录入的TextBox,在焦点切换的过程中完成background input和agent input的属性同步。 下面的代码完成两个input之间的样式和属性同步: function ATB_SwitchToInputAgent(input)
function ATB_AutoIncreaseWidth(input) { if ( input.style.display == 'none' ) return; var spanWrapper = input.parentElement; var userInput = spanWrapper.firstChild; userInput.value = input.value; var absOffsetWidth = GetAbsoluteOffsetLeft(input); var docClientWidth = window.document.body.clientWidth; if ( input.scrollWidth < userInput.clientWidth ) { if ( absOffsetWidth + styleWidth >= docClientWidth ) { input.style.width = docClientWidth - absOffsetWidth; } else { input.style.width = userInput.clientWidth+2; } return; } var styleWidth = parseInt(input.style.width); if ( styleWidth != input.scrollWidth+2 ) { if ( absOffsetWidth + styleWidth >= docClientWidth ) { input.style.width = docClientWidth - absOffsetWidth; } else { input.style.width = input.scrollWidth+2; } } }
* |
#region 附 AdjustableTextBox 控件源码 using System; using System.IO; using System.Drawing; using System.Text; using System.Web.UI; using System.Web.UI.WebControls; using System.ComponentModel; namespace WebExcel.UI.WebControls { /// <summary> /// Summary description for AdjustableTextBox. /// </summary> [DefaultProperty("Text")] [ToolboxData("<{0}:AdjustableTextBox runat=server></{0}:AdjustableTextBox>")] public class AdjustableTextBox : TextBox { public Color AgentBorderColor { get { object obj = ViewState["AgentBorderColor"]; return obj == null ? Color.Gray : (Color)obj; } set { ViewState["AgentBorderColor"] = value; } } public bool AutoIncrease { get { object obj = ViewState["AutoIncrease"]; return obj == null ? true : ( bool)obj; } set { ViewState["AutoIncrease"] = value; } } // the property is always TextBoxMode.SingleLine. public override TextBoxMode TextMode { get { return base.TextMode; } set { base.TextMode = value; if ( value != TextBoxMode.SingleLine ) { this.AutoIncrease = false; } else { this.AutoIncrease = true; } } } public new Unit BorderWidth { get { if ( base.BorderWidth == Unit.Empty ) { base.BorderWidth = 1; } return base.BorderWidth; } set { if ( value != Unit.Empty ) { base.BorderWidth = value; } } } /// <summary> /// Render this control to the output parameter specified. /// </summary> /// <param name="output"> The HTML writer to write out to </param> protected override void Render(HtmlTextWriter output) { if ( this.AutoIncrease ) { this.RegisterClientScript(); base.Attributes["onfocus"] = "ATB_SwitchToInputAgent(this)"; base.Attributes.CssStyle["position"] = "relative"; if ( base.BorderWidth == Unit.Empty ) { base.BorderWidth = 1; } string spanWrapper = @"<span style='z-index: 1; position: relative; border: solid 0px black;'>{0}<input type='text' οnblur='ATB_GetAgentValue(this)' onpropertychange='ATB_AutoIncreaseWidth(this)' style='border: solid 1px gray; position: absolute; display:none;' /></span>"; StringBuilder sb = new StringBuilder(); StringWriter sw = new StringWriter(sb); HtmlTextWriter htw = new HtmlTextWriter(sw); base.Render(htw); output.Write( string.Format(spanWrapper, sb.ToString(), ColorTranslator.ToHtml( this.AgentBorderColor))); } else { // base.Attributes["onfocus"] = "this.height='100%'"; base.Render(output); } } private void RegisterClientScript() { const string COMMON_SCRIPT_KEY = "__CommonJavaScript__"; string strCommon = @"<script language='javascript'> function GetAbsoluteOffsetLeft(element) { if ( element == null || arguments.length != 1 ) { return; } var offsetLeft = element.offsetLeft; while( element = element.offsetParent ) { offsetLeft += element.offsetLeft; } return offsetLeft; } </script>"; if ( ! this.Page.IsStartupScriptRegistered(COMMON_SCRIPT_KEY) ) { this.Page.RegisterStartupScript(COMMON_SCRIPT_KEY, strCommon); } const string SCRIPT_KEY = "__AdjustableTextBoxKey__"; string strScript = @" <script language='javascript'> function ATB_SwitchToInputAgent(input) { if ( input.disabled ) return; var spanWrapper = input.parentElement; var agentInput = spanWrapper.lastChild; var userOffsetTop, userOffsetLeft; with(input.style) { var userMarginTop = parseInt(marginTop); var userMarginLeft = parseInt(marginLeft); var userBorderTop = parseInt(borderTopWidth); var userBorderLeft = parseInt(borderLeftWidth); userMarginTop = isNaN(userMarginTop) ? 0 : userMarginTop; userMarginLeft = isNaN(userMarginLeft) ? 0 : userMarginLeft; userBorderTop = isNaN(userBorderTop) ? 0 : userBorderTop; userBorderLeft = isNaN(userBorderLeft) ? 0 : userBorderLeft; userOffsetTop = userBorderTop + userMarginTop; userOffsetLeft = userBorderLeft + userMarginLeft; } var retouch = 0; agentInput.value = input.value; // must be mdified at first agentInput.style.top = userOffsetTop; agentInput.style.left = userOffsetLeft-1; spanWrapper.style.zIndex = 10; agentInput.style.display = 'inline'; agentInput.style.borderWdith = input.style.borderWdith; agentInput.style.borderColor = input.style.borderColor; agentInput.style.backgroundColor = input.style.backgroundColor; agentInput.style.color = input.style.color; agentInput.style.fontFamily = input.style.fontFamily; agentInput.style.fontWegith = input.style.fontWeight; agentInput.style.fontSize = input.style.fontSize; agentInput.style.height = input.style.height; var absOffsetWidth = GetAbsoluteOffsetLeft(input); var docClientWidth = window.document.body.clientWidth; var styleWidth = parseInt(agentInput.style.width); if ( absOffsetWidth + styleWidth >= docClientWidth ) { agentInput.style.width = docClientWidth - absOffsetWidth; } else { agentInput.style.width = input.clientWidth+2; } agentInput.style.fontStyle = input.style.fontStyle; try { agentInput.style.font = input.style.font } catch(exp){}; agentInput.style.fontVariant = input.style.fontVariant; agentInput.style.zoom = input.style.zoom; agentInput.readOnly = input.readOnly; // agentInput.focus(); must remove!!! if ( !agentInput.readOnly ) { agentInput.select(); } } function ATB_GetAgentValue(input) { var spanWrapper = input.parentElement; var userInput = spanWrapper.firstChild; input.style.width = userInput.clientWidth+2; spanWrapper.style.zIndex = 1; userInput.value = input.value; input.style.display = 'none'; } function ATB_AutoIncreaseWidth(input) { if ( input.style.display == 'none' ) return; var spanWrapper = input.parentElement; var userInput = spanWrapper.firstChild; userInput.value = input.value; var absOffsetWidth = GetAbsoluteOffsetLeft(input); var docClientWidth = window.document.body.clientWidth; if ( input.scrollWidth < userInput.clientWidth ) { if ( absOffsetWidth + styleWidth >= docClientWidth ) { input.style.width = docClientWidth - absOffsetWidth; } else { input.style.width = userInput.clientWidth+2; } return; } var styleWidth = parseInt(input.style.width); if ( styleWidth != input.scrollWidth+2 ) { if ( absOffsetWidth + styleWidth >= docClientWidth ) { input.style.width = docClientWidth - absOffsetWidth; } else { input.style.width = input.scrollWidth+2; } } } </script>"; if ( ! this.Page.IsStartupScriptRegistered(SCRIPT_KEY) ) { this.Page.RegisterStartupScript(SCRIPT_KEY, strScript); } } } } #endregion