DavidJGu's Blog

       尼采说,宁可追求虚无也不能无所追求!  Keeping is harder than winning
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

在aspx页面动态添加控件

Posted on 2005-04-20 19:10  Let's DotNet  阅读(2067)  评论(0编辑  收藏  举报

[是说“生成一个动态页面”还是“动态生成页面”?都不是。我们要在一个aspx页面里动态生成一些控件,用于交互(不是只读)。]


一般来说有两种方法可以在页面里根据实际需要生成页面控件:

    1-javascript;

    2-在Response结束前增加控件对象!
我们这里要采用第二种方法,因为用javascript的方法在交互时保存值和刷新值会很麻烦。

来看第二种方法。实际上很简单,只是在当前页面对象上添加所需要添加的控件而已。

为了显示布局的需要,通常会在一个Table(也可以用PlaceHolder)里加这些控件(当然此时要把Table设为runat="server")。
这时要注意的几点是:
    1.动态加载控件的动作每次postback都必须重来一次,即不要只在页面load时添加;
    2.把放置控件的容器型控件的EnableViewState属性设为false;原因是如果两次页面交互所生成的控件不同时,会先比较viewstate,如果有viewstate数据则会报错;
    3.动态添加的自定义控件必须是web自定义控件而非web用户控件,后者不能动态生成是因为依赖于前台页面;

本文主要想给出一种基于实际业务的结构设计。

一般而言我们为了完成某个业务需要在页面动态添加用来获取或设置的业务属性的控件,所以第一步是产生连接业务点和显

示控制的业务属性与设计类。

属性设计类AttributeDesign{属性ID,属性名称,属性值,属性数据类型,属性单位,属性表现形式,属性是否只读,属性是否数字,是否有计量单位, 属性关系,是否允许为NULL,默认值}

业务设计类OperationDesign{业务属性类集合,嵌套业务属性(子业务属性),压缩数据集合(上传文件),methond:得到属性列表、 初始化值}

页面设计帮助类PageDesignHelper{根据需求,定制相应的控件对象,如HtmlTableRow等;调用时须传入(是否只读,id,默认值,标签值,宿主页面)等参数}

页面交互帮助类PageOperationHelper{清除操作,数据验证(类型验证-整型 日期 。。。),读取控件值(图片?),业务验证,数据保存,加载控件到宿主页面(同时添加事件绑定,并调用)}

 

整体结构图如下:


 

 

 

解释:

1.属性设计类是动态页面交互的最基础的元素;业务设计类则把这些“属性”集中起来,并对它们进行一些基本操作,如赋初值。

更重要的作用时进行一些特殊处理,比如存放压缩数据、暂存数据。一个图片型(或文件型)的控件的值是不能简单存放在控件里的,所以如果要批量处理,必须暂存在自定义的对象里;

2.页面交互帮助类是逻辑与前台之间的桥梁,发挥着重要的接力作用;负责控件的添加、数据管理和动态控件的事件绑定。那么为什么要进行“动态控件的事件绑定”?这是因为我们在页面交互时有可能因为业务的需要动态改变控件的显示特性,比如当下拉框选中某个值时自动隐藏另外一个或多个控件。这个动作必须由此类完成,因为它负责调用页面设计帮助类来生成控件,只有当控件生成了,才能对其进行事件绑定。

3.页面设计帮助类所完成的事情则相对单一,根据要求生成控件。如下面的示例:

/// <summary>
/// 定制一个文本输入行
/// </summary>
/// <param name="bReadOnly">文本框是否只读</param>
/// <param name="strID">文本框ID</param>
/// <param name="strLabelText">标签名</param>
/// <returns>HtmlTableRow</returns>

public static System.Web.UI.HtmlControls.HtmlTableRow InputTextBoxRow(bool bReadOnly,string strID,string strLabelText)
{
System.Web.UI.HtmlControls.HtmlTableRow objTableRow
= new HtmlTableRow();
objTableRow.ID
= CommonEnum.TRPrefix+strID;
objTableRow.VAlign
= "middle";
objTableRow.Cells.Add(LabelCell(strID,strLabelText));
objTableRow.Cells.Add(SpanCell());
objTableRow.Cells.Add(TextBoxCell(bReadOnly,strID));
objTableRow.Cells.Add(SpanCell());

return objTableRow;
}



/// <summary>
/// 带默认值的定制文本输入行
/// </summary>
/// <param name="bReadOnly">文本框是否只读</param>
/// <param name="strID">文本框</param>
/// <param name="strLabelText">标签名</param>
/// <param name="strDefaultValue">默认值</param>
/// <returns>HtmlTableRow</returns>

public static System.Web.UI.HtmlControls.HtmlTableRow InputTextBoxRow(bool bReadOnly,string strID,string strLabelText,string strDefaultValue)
{
System.Web.UI.HtmlControls.HtmlTableRow objTableRow
= new HtmlTableRow();
objTableRow.ID
= CommonEnum.TRPrefix+strID;
objTableRow.VAlign
= "middle";
objTableRow.Cells.Add(LabelCell(strID,strLabelText));
objTableRow.Cells.Add(SpanCell());
objTableRow.Cells.Add(TextBoxCell(bReadOnly,strID,strDefaultValue));
objTableRow.Cells.Add(SpanCell());

return objTableRow;
}


/// <summary>
/// 带单位的定制文本输入行
/// </summary>
/// <param name="bReadOnly">文本框是否只读</param>
/// <param name="strID">文本框</param>
/// <param name="strLabelText">标签名</param>
/// <param name="objDdl">单位选择下拉列表</param>
/// <returns>HtmlTableRow</returns>

public static System.Web.UI.HtmlControls.HtmlTableRow InputTextBoxRow(bool bReadOnly,string strID,string strLabelText,System.Web.UI.WebControls.DropDownList objDdl)
{
System.Web.UI.HtmlControls.HtmlTableRow objTableRow
= new HtmlTableRow();
objTableRow.ID
= CommonEnum.TRPrefix+strID;
objTableRow.VAlign
= "middle";
objTableRow.Cells.Add(LabelCell(strID,strLabelText));
objTableRow.Cells.Add(SpanCell());
objDdl.Attributes.Add(
"Class","DropDownList");
objTableRow.Cells.Add(TextBoxCell(bReadOnly,strID,objDdl));
objTableRow.Cells.Add(SpanCell());

return objTableRow;

}



/// <summary>
/// 带单位和默认值的定制文本输入行
/// </summary>
/// <param name="bReadOnly">文本框是否只读</param>
/// <param name="strID">文本框</param>
/// <param name="strLabelText">标签名</param>
/// <param name="objDdl">单位选择下拉列表</param>
/// <param name="strDefaultTextBoxValue">文本框缺省值</param>
/// <returns>HtmlTableRow</returns>

public static System.Web.UI.HtmlControls.HtmlTableRow InputTextBoxRow(bool bReadOnly,string strID,string strLabelText,System.Web.UI.WebControls.DropDownList objDdl,string strDefaultTextBoxValue)
{
System.Web.UI.HtmlControls.HtmlTableRow objTableRow
= new HtmlTableRow();
objTableRow.ID
= CommonEnum.TRPrefix+strID;
objTableRow.VAlign
= "middle";
objTableRow.Cells.Add(LabelCell(strID,strLabelText));
objTableRow.Cells.Add(SpanCell());
objDdl.Attributes.Add(
"Class","DropDownList");
objTableRow.Cells.Add(TextBoxCell(bReadOnly,strID,objDdl,strDefaultTextBoxValue));
objTableRow.Cells.Add(SpanCell());

return objTableRow;

}

 

 综上,比较复杂一些的就是页面交互帮助类了。

 当然,更好的设计是可以定义一些属性与属性间的业务关系。因为实际项目时间紧,做的时候就没有好好细化