博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自动适应输入内容宽度的TextBox控件
阅读量:6909 次
发布时间:2019-06-27

本文共 7561 字,大约阅读时间需要 25 分钟。

在ASP.NET的上面,TextBox是表单设计时最常用的控件之一。很多时候为了页面的紧凑和美观,我们需要适当的限制TextBox的显示宽度,但是如果TextBox过于窄了之后,又会给用户的填写带了不便,而且更麻烦的是很多时候我们并不知道用户到底会往那个TextBox里填多少内容。为了解决这些问题,下面给大家推荐一个可自动适应输入内容的宽度的TextBox控件。

    本控件是从TextBox控件继承,设计原理是使用一个agent input(type=text)来做为实际的用户录入的TextBox,在焦点切换的过程中完成background input和agent input的属性同步。 
    下面的代码完成两个input之间的样式和属性同步:

ContractedBlock.gif
function ATB_SwitchToInputAgent(input) 
    注意:不能使用style=style或for( attribute in style)的方式来赋值,否这引起onpropertychange的死循环递归
emcrook.gif
    第二个问题是使用onpropertychange属性来同步agent input的宽度和其内容宽度相等,代码如下: 
None.gif
function ATB_AutoIncreaseWidth(input) 
None.gif
None.gif    
if ( input.style.display == 'none' ) 
return
None.gif    
var spanWrapper = input.parentElement; 
None.gif    
var userInput = spanWrapper.firstChild; 
None.gif    userInput.value = input.value; 
None.gif    
var absOffsetWidth = GetAbsoluteOffsetLeft(input); 
None.gif    
var docClientWidth = window.document.body.clientWidth; 
None.gif    
if ( input.scrollWidth < userInput.clientWidth ) 
None.gif    { 
None.gif        
if ( absOffsetWidth + styleWidth >= docClientWidth )  
None.gif        { 
None.gif            input.style.width = docClientWidth - absOffsetWidth; 
None.gif        } 
None.gif        
else 
None.gif        { 
None.gif            input.style.width = userInput.clientWidth+2; 
None.gif        } 
None.gif        
return
None.gif    } 
None.gif    
var styleWidth = parseInt(input.style.width); 
None.gif    
if ( styleWidth != input.scrollWidth+2 ) 
None.gif    { 
None.gif        
if ( absOffsetWidth + styleWidth >= docClientWidth )  
None.gif        { 
None.gif            input.style.width = docClientWidth - absOffsetWidth; 
None.gif        } 
None.gif        
else 
None.gif        { 
None.gif            input.style.width = input.scrollWidth+2; 
None.gif        } 
None.gif    } 
None.gif
    这里需要注意的是当增长的agent input的最右端超出了IE的body区域时,需要停止其增长,否则用户看不见输入的东西了。 
    演示效果如下:
    
*
ExpandedBlockStart.gif
#region 附 AdjustableTextBox 控件源码
InBlock.gif
using System;
InBlock.gif
using System.IO;
InBlock.gif
using System.Drawing;
InBlock.gif
using System.Text;
InBlock.gif
using System.Web.UI;
InBlock.gif
using System.Web.UI.WebControls;
InBlock.gif
using System.ComponentModel;
InBlock.gif
InBlock.gif
namespace WebExcel.UI.WebControls
ExpandedSubBlockStart.gif{
ExpandedSubBlockStart.gif    
///
 
<summary>
InBlock.gif    
///
 Summary description for AdjustableTextBox.
ExpandedSubBlockEnd.gif    
///
 
</summary>
InBlock.gif    [DefaultProperty("Text")]
InBlock.gif    [ToolboxData("<{0}:AdjustableTextBox runat=server></{0}:AdjustableTextBox>")]
InBlock.gif    
public 
class AdjustableTextBox : TextBox
ExpandedSubBlockStart.gif    {
InBlock.gif        
public Color AgentBorderColor
ExpandedSubBlockStart.gif        {
InBlock.gif            
get
ExpandedSubBlockStart.gif            {
InBlock.gif                
object obj = ViewState["AgentBorderColor"];
InBlock.gif                
return obj == 
null ? Color.Gray : (Color)obj;
ExpandedSubBlockEnd.gif            }
InBlock.gif            
set
ExpandedSubBlockStart.gif            {
InBlock.gif                ViewState["AgentBorderColor"] = value;
ExpandedSubBlockEnd.gif            }
ExpandedSubBlockEnd.gif        }
InBlock.gif
InBlock.gif        
public 
bool AutoIncrease
ExpandedSubBlockStart.gif        {
InBlock.gif            
get
ExpandedSubBlockStart.gif            {
InBlock.gif                
object obj = ViewState["AutoIncrease"];
InBlock.gif                
return obj == 
null ? 
true : (
bool)obj;
ExpandedSubBlockEnd.gif            }
InBlock.gif            
set
ExpandedSubBlockStart.gif            {
InBlock.gif                ViewState["AutoIncrease"] = value;
ExpandedSubBlockEnd.gif            }
ExpandedSubBlockEnd.gif        }
InBlock.gif
InBlock.gif        
//
 the property is always TextBoxMode.SingleLine.
InBlock.gif
        
public 
override TextBoxMode TextMode
ExpandedSubBlockStart.gif        {
InBlock.gif            
get
ExpandedSubBlockStart.gif            {
InBlock.gif                
return 
base.TextMode;
ExpandedSubBlockEnd.gif            }
InBlock.gif            
set
ExpandedSubBlockStart.gif            {
InBlock.gif                
base.TextMode = value;
InBlock.gif                
if ( value != TextBoxMode.SingleLine )
ExpandedSubBlockStart.gif                {
InBlock.gif                    
this.AutoIncrease = 
false;
ExpandedSubBlockEnd.gif                }
InBlock.gif                
else
ExpandedSubBlockStart.gif                {
InBlock.gif                    
this.AutoIncrease = 
true;
ExpandedSubBlockEnd.gif                }
ExpandedSubBlockEnd.gif            }
ExpandedSubBlockEnd.gif        }
InBlock.gif
InBlock.gif        
public 
new Unit BorderWidth
ExpandedSubBlockStart.gif        {
InBlock.gif            
get
ExpandedSubBlockStart.gif            {
InBlock.gif                
if ( 
base.BorderWidth == Unit.Empty )
ExpandedSubBlockStart.gif                {
InBlock.gif                    
base.BorderWidth = 1;
ExpandedSubBlockEnd.gif                }
InBlock.gif                
return 
base.BorderWidth;
ExpandedSubBlockEnd.gif            }
InBlock.gif            
set
ExpandedSubBlockStart.gif            {
InBlock.gif                
if ( value != Unit.Empty )
ExpandedSubBlockStart.gif                {
InBlock.gif                    
base.BorderWidth = value;
ExpandedSubBlockEnd.gif                }
ExpandedSubBlockEnd.gif            }
ExpandedSubBlockEnd.gif        }
InBlock.gif
ExpandedSubBlockStart.gif        
///
 
<summary>
 
InBlock.gif        
///
 Render this control to the output parameter specified.
InBlock.gif        
///
 
</summary>
ExpandedSubBlockEnd.gif        
///
 
<param name="output">
 The HTML writer to write out to 
</param>
InBlock.gif        
protected 
override 
void Render(HtmlTextWriter output)
ExpandedSubBlockStart.gif        {
InBlock.gif            
if ( 
this.AutoIncrease )
ExpandedSubBlockStart.gif            {
InBlock.gif                
this.RegisterClientScript();
InBlock.gif                
base.Attributes["onfocus"] = "ATB_SwitchToInputAgent(this)";
InBlock.gif                
base.Attributes.CssStyle["position"] = "relative";
InBlock.gif                
if ( 
base.BorderWidth == Unit.Empty )
ExpandedSubBlockStart.gif                {
InBlock.gif                    
base.BorderWidth = 1;
ExpandedSubBlockEnd.gif                }
InBlock.gif                
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>";
InBlock.gif                StringBuilder sb = 
new StringBuilder();
InBlock.gif                StringWriter sw = 
new StringWriter(sb);
InBlock.gif                HtmlTextWriter htw = 
new HtmlTextWriter(sw);
InBlock.gif                
base.Render(htw);
InBlock.gif                output.Write(
string.Format(spanWrapper, sb.ToString(), ColorTranslator.ToHtml(
this.AgentBorderColor)));
ExpandedSubBlockEnd.gif            }
InBlock.gif            
else
ExpandedSubBlockStart.gif            {
InBlock.gif                
//
 base.Attributes["onfocus"] = "this.height='100%'";
InBlock.gif
                
base.Render(output);
ExpandedSubBlockEnd.gif            }
ExpandedSubBlockEnd.gif        }
InBlock.gif
InBlock.gif        
private 
void RegisterClientScript()
ExpandedSubBlockStart.gif        {
InBlock.gif            
const 
string COMMON_SCRIPT_KEY = "__CommonJavaScript__";
InBlock.gif            
string strCommon = @"<script language='javascript'>
InBlock.gif            function GetAbsoluteOffsetLeft(element)
ExpandedSubBlockStart.gif            {
InBlock.gif                
if ( element == 
null || arguments.length != 1 )
ExpandedSubBlockStart.gif                {
InBlock.gif                    
return;
ExpandedSubBlockEnd.gif                }
InBlock.gif                var offsetLeft = element.offsetLeft;
InBlock.gif                
while( element = element.offsetParent )
ExpandedSubBlockStart.gif                {
InBlock.gif                    offsetLeft += element.offsetLeft;
ExpandedSubBlockEnd.gif                }
InBlock.gif                
return offsetLeft;
ExpandedSubBlockEnd.gif            }
InBlock.gif            </script>";
InBlock.gif            
if ( !
this.Page.IsStartupScriptRegistered(COMMON_SCRIPT_KEY) )
ExpandedSubBlockStart.gif            {
InBlock.gif                
this.Page.RegisterStartupScript(COMMON_SCRIPT_KEY, strCommon);
ExpandedSubBlockEnd.gif            }
InBlock.gif
InBlock.gif            
const 
string SCRIPT_KEY = "__AdjustableTextBoxKey__";
InBlock.gif            
string strScript = @"
InBlock.gif                <script language='javascript'>
InBlock.gif                function ATB_SwitchToInputAgent(input)
ExpandedSubBlockStart.gif                {
InBlock.gif                    
if ( input.disabled ) 
return;
InBlock.gif                    var spanWrapper = input.parentElement;
InBlock.gif                    var agentInput = spanWrapper.lastChild;
InBlock.gif                    var userOffsetTop, userOffsetLeft;
InBlock.gif                    with(input.style)
ExpandedSubBlockStart.gif                    {
InBlock.gif                        var userMarginTop = parseInt(marginTop);
InBlock.gif                        var userMarginLeft = parseInt(marginLeft);
InBlock.gif                        var userBorderTop = parseInt(borderTopWidth);
InBlock.gif                        var userBorderLeft = parseInt(borderLeftWidth);
InBlock.gif                        userMarginTop = isNaN(userMarginTop) ? 0 : userMarginTop;
InBlock.gif                        userMarginLeft = isNaN(userMarginLeft) ? 0 : userMarginLeft;
InBlock.gif                        userBorderTop = isNaN(userBorderTop) ? 0 : userBorderTop;
InBlock.gif                        userBorderLeft = isNaN(userBorderLeft) ? 0 : userBorderLeft;
InBlock.gif                        userOffsetTop = userBorderTop + userMarginTop;
InBlock.gif                        userOffsetLeft = userBorderLeft + userMarginLeft;
ExpandedSubBlockEnd.gif                    }
InBlock.gif                    var retouch = 0;
InBlock.gif                    agentInput.value = input.value; 
//
 must be mdified at first
InBlock.gif
                    agentInput.style.top = userOffsetTop;
InBlock.gif                    agentInput.style.left = userOffsetLeft-1;
InBlock.gif                    spanWrapper.style.zIndex = 10;
InBlock.gif                    agentInput.style.display = 'inline';
InBlock.gif                    agentInput.style.borderWdith = input.style.borderWdith;
InBlock.gif                    agentInput.style.borderColor = input.style.borderColor;
InBlock.gif                    agentInput.style.backgroundColor = input.style.backgroundColor;
InBlock.gif                    agentInput.style.color = input.style.color;
InBlock.gif                    agentInput.style.fontFamily = input.style.fontFamily;
InBlock.gif                    agentInput.style.fontWegith = input.style.fontWeight;
InBlock.gif                    agentInput.style.fontSize = input.style.fontSize;
InBlock.gif                    agentInput.style.height = input.style.height;
InBlock.gif                    var absOffsetWidth = GetAbsoluteOffsetLeft(input);
InBlock.gif                    var docClientWidth = window.document.body.clientWidth;
InBlock.gif                    var styleWidth = parseInt(agentInput.style.width);
InBlock.gif                    
if ( absOffsetWidth + styleWidth >= docClientWidth ) 
ExpandedSubBlockStart.gif                    {
InBlock.gif                        agentInput.style.width = docClientWidth - absOffsetWidth;
ExpandedSubBlockEnd.gif                    }
InBlock.gif                    
else
ExpandedSubBlockStart.gif                    {
InBlock.gif                        agentInput.style.width = input.clientWidth+2;
ExpandedSubBlockEnd.gif                    }
InBlock.gif                    agentInput.style.fontStyle = input.style.fontStyle;
ExpandedSubBlockStart.gif                    
try { agentInput.style.font = input.style.font } 
catch(exp){};
InBlock.gif                    agentInput.style.fontVariant = input.style.fontVariant;
InBlock.gif                    agentInput.style.zoom = input.style.zoom;
InBlock.gif                    agentInput.readOnly = input.readOnly;
InBlock.gif                    
//
agentInput.focus(); must remove!!!
InBlock.gif
                    
if ( !agentInput.readOnly )
ExpandedSubBlockStart.gif                    {        
InBlock.gif                        agentInput.select();
ExpandedSubBlockEnd.gif                    }
ExpandedSubBlockEnd.gif                }
InBlock.gif
InBlock.gif                function ATB_GetAgentValue(input)
ExpandedSubBlockStart.gif                {
InBlock.gif                    var spanWrapper = input.parentElement;
InBlock.gif                    var userInput = spanWrapper.firstChild;
InBlock.gif                    input.style.width = userInput.clientWidth+2;
InBlock.gif                    spanWrapper.style.zIndex = 1;
InBlock.gif                    userInput.value = input.value;
InBlock.gif                    input.style.display = 'none';
ExpandedSubBlockEnd.gif                }
InBlock.gif                
InBlock.gif                function ATB_AutoIncreaseWidth(input)
ExpandedSubBlockStart.gif                {
InBlock.gif                    
if ( input.style.display == 'none' ) 
return;
InBlock.gif                    var spanWrapper = input.parentElement;
InBlock.gif                    var userInput = spanWrapper.firstChild;
InBlock.gif                    userInput.value = input.value;
InBlock.gif                    var absOffsetWidth = GetAbsoluteOffsetLeft(input);
InBlock.gif                    var docClientWidth = window.document.body.clientWidth;
InBlock.gif                    
if ( input.scrollWidth < userInput.clientWidth )
ExpandedSubBlockStart.gif                    {
InBlock.gif                        
if ( absOffsetWidth + styleWidth >= docClientWidth ) 
ExpandedSubBlockStart.gif                        {
InBlock.gif                            input.style.width = docClientWidth - absOffsetWidth;
ExpandedSubBlockEnd.gif                        }
InBlock.gif                        
else
ExpandedSubBlockStart.gif                        {
InBlock.gif                            input.style.width = userInput.clientWidth+2;
ExpandedSubBlockEnd.gif                        }
InBlock.gif                        
return;
ExpandedSubBlockEnd.gif                    }
InBlock.gif                    var styleWidth = parseInt(input.style.width);
InBlock.gif                    
if ( styleWidth != input.scrollWidth+2 )
ExpandedSubBlockStart.gif                    {
InBlock.gif                        
if ( absOffsetWidth + styleWidth >= docClientWidth ) 
ExpandedSubBlockStart.gif                        {
InBlock.gif                            input.style.width = docClientWidth - absOffsetWidth;
ExpandedSubBlockEnd.gif                        }
InBlock.gif                        
else
ExpandedSubBlockStart.gif                        {
InBlock.gif                            input.style.width = input.scrollWidth+2;
ExpandedSubBlockEnd.gif                        }
ExpandedSubBlockEnd.gif                    }
ExpandedSubBlockEnd.gif                }
InBlock.gif                </script>";
InBlock.gif            
if ( !
this.Page.IsStartupScriptRegistered(SCRIPT_KEY) )
ExpandedSubBlockStart.gif            {
InBlock.gif                
this.Page.RegisterStartupScript(SCRIPT_KEY, strScript);
ExpandedSubBlockEnd.gif            }
ExpandedSubBlockEnd.gif        }
ExpandedSubBlockEnd.gif    }
ExpandedSubBlockEnd.gif}
ExpandedBlockEnd.gif
#endregion

本文转自博客园鸟食轩的博客,原文链接:http://www.cnblogs.com/birdshome/,如需转载请自行联系原博主。

你可能感兴趣的文章
Windows 2012 Hyper –V 3.0 New Functions
查看>>
maven部分插件配置demo
查看>>
BZOJ 2818GCD
查看>>
提交包到iTunes Connect时构建版本“正在处理”后直接消失的问题
查看>>
我的友情链接
查看>>
QQ空间技术架构之深刻揭密
查看>>
nfs常见问题解决方法
查看>>
centOS 6 安装mongoDB
查看>>
Java基础学习总结(10)——static关键字
查看>>
大型网站技术架构(六)网站的伸缩性架构
查看>>
Linux实用工具
查看>>
JDBC Statement 实例- 查询结果集
查看>>
Java消息服务JMS详解
查看>>
Grin交易原理详解
查看>>
磁盘分区以及挂接挂载
查看>>
大数据体系【概念认知】系列-2:存储以及副本策略
查看>>
Android Hacks:同时启动多个Intent
查看>>
简明的数据库设计模式
查看>>
我的友情链接
查看>>
linux企业常用服务---haproxy+nginx搭建web高可用集群
查看>>