从简单做起---ASP.NET复合控件(修定版)

从简单做起---ASP.NET复合控件

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

在你的网页应用程序里面添加用户控件,真的很简单。事实上,你只是做了网页的一部分,添加HTML,然后在应用程序里面使用。尽管用着很简单,但是不方便在应用程序间共享。有一种控件复合性控件,做起来很复杂,但是用着很方便,它可以很方便地在不同的应用程序之间多次使用。这里我们就简单介绍这种控件的生成方法。

 

我们可以使用MS内置控件,如Textbox等来组建你的复合控件,当然,也可以用自己定义Layout。在这里我们放三个Textbox,让用户来输入日期,当然还有一些逻辑代码来合并这些日期成为一个完整的日期格式。

 

在这个DEMO中你要建两个工程,一个是复合控件工程Web Control Library,一个是引用这个复合控件的WEB程序。在这里,我们的前者工程叫做,DateEditBox,完成后,会有一个DateEditBox的类。以下这个类的主要信息:

 

 

None.gif namespace  MyControls
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   [DefaultProperty(
"Value")]
InBlock.gif   [ToolboxData(
"<{0}:DateEditBox runat=server></{0}:DateEditBox>")]
InBlock.gif   
public class DateEditBox : CompositeControl
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      
private TextBox txtMonth = new TextBox();
InBlock.gif      
private TextBox txtDay   = new TextBox();
InBlock.gif      
private TextBox txtYear  = new TextBox();
InBlock.gif
InBlock.gif      
protected override void OnInit(EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif         
base.OnInit(e);
InBlock.gif         txtMonth.ID        
= this.ID + "_month";
InBlock.gif         txtMonth.MaxLength 
= 2;
InBlock.gif         txtMonth.Width     
= this.Width;
InBlock.gif
InBlock.gif         txtDay.ID        
= this.ID + "_day";
InBlock.gif         txtDay.MaxLength 
= 2;
InBlock.gif         txtDay.Width     
= this.Width;
InBlock.gif
InBlock.gif         txtYear.ID        
= this.ID + "_year";
InBlock.gif         txtYear.MaxLength 
= 4;
InBlock.gif         txtYear.Width     
= this.Width;
ExpandedSubBlockEnd.gif      }

InBlock.gif
InBlock.gif      [Bindable(
true)]
InBlock.gif      [Category(
"Appearance")]
InBlock.gif      [DefaultValue(
"")]
InBlock.gif      [Localizable(
true)]
InBlock.gif      
public DateTime Value
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif         
get
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif            EnsureChildControls();
InBlock.gif            
if (txtMonth.Text == "" || txtDay.Text == "" ||
InBlock.gif                txtYear.Text 
== "")
InBlock.gif               
return DateTime.MinValue;
InBlock.gif            
else
InBlock.gif               
return new DateTime(Convert.ToInt32(txtYear.Text),
InBlock.gif                  Convert.ToInt32(txtMonth.Text),
InBlock.gif                  Convert.ToInt32(txtDay.Text));
ExpandedSubBlockEnd.gif         }

InBlock.gif
InBlock.gif         
set
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif            EnsureChildControls();
InBlock.gif            txtMonth.Text 
= value.Month.ToString();
InBlock.gif            txtDay.Text   
= value.Day.ToString();
InBlock.gif            txtYear.Text  
= value.Year.ToString();
ExpandedSubBlockEnd.gif         }

ExpandedSubBlockEnd.gif      }

InBlock.gif      
protected override void CreateChildControls()
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif         
this.Controls.Add(txtMonth);
InBlock.gif         
this.Controls.Add(txtDay);
InBlock.gif         
this.Controls.Add(txtYear);
InBlock.gif         
base.CreateChildControls();
ExpandedSubBlockEnd.gif      }

InBlock.gif      
public override void RenderControl(HtmlTextWriter writer)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif         writer.RenderBeginTag(HtmlTextWriterTag.Table);
InBlock.gif         writer.RenderBeginTag(HtmlTextWriterTag.Tr);
InBlock.gif         writer.RenderBeginTag(HtmlTextWriterTag.Td);
InBlock.gif         txtMonth.RenderControl(writer);
InBlock.gif         writer.RenderEndTag();    
// td
InBlock.gif
         writer.RenderBeginTag(HtmlTextWriterTag.Td);
InBlock.gif         writer.Write(
"/");
InBlock.gif         writer.RenderEndTag();    
// td
InBlock.gif
         writer.RenderBeginTag(HtmlTextWriterTag.Td);
InBlock.gif         txtDay.RenderControl(writer);
InBlock.gif         writer.RenderEndTag();    
// td
InBlock.gif
         writer.RenderBeginTag(HtmlTextWriterTag.Td);
InBlock.gif         writer.Write(
"/");
InBlock.gif         writer.RenderEndTag();    
// td
InBlock.gif
         writer.RenderBeginTag(HtmlTextWriterTag.Td);
InBlock.gif         txtYear.RenderControl(writer);
InBlock.gif         writer.RenderEndTag();    
// td
InBlock.gif
         writer.RenderEndTag();    // tr
InBlock.gif
         writer.RenderEndTag();    // table
ExpandedSubBlockEnd.gif
      }

ExpandedSubBlockEnd.gif   }

ExpandedBlockEnd.gif}

None.gif
None.gif

 

 

这个类有点复杂,让我们来分析一下。我个内是以一些属性定义开始的。第一个是默认值,用来指定值的属性。第二个是用来指定本控件可以用在WEB页面的,一般是从VS工具箱拖拉到页面上的。你也注意到了,这个类是继承至CompositeControl,,这个内是专为自定义复合控件定制的。关于这个类的详细信息可以查看MSDN

 

OnInit事件里,我们给这三个子控件设置一些默认值,如ID,宽度,字长等。我们设置ID以复控件ID开头,是因为在后面我们将用这些ID来查找这些控件。

 

我们有值属性设置器,就可以很方便的设置和读取它们各自的值,当然,在这里,你完全可以加入一些基本的验证。在这里就不说这些了。接下来就是CreateChildControls方法和RenderControl方法。前者可以让页面在回传的时候保存控件状态。如果没有这方法,你的子控件就不能保存视图状态,所以也不能正常显示在回传页面的时候。后一个方法负责让你的控件在页面上正常显示。这样的话,你的控件就会显示以下格式:

None.gif table
None.gif   tr
None.gif      td [txtMonth] /td
None.gif      td [/] /td
None.gif      td [txtDay] /td
None.gif      td [/] /td
None.gif      td [txtYear] /td
None.gif   /tr
None.gif/table
None.gif

 

当然在HtmlTextWriter里面你也可以自己定义你的样式,排版等。如果你想在其它工程中引用这个控件的话,首先要编译,成功后会在BIN里面出现*.dll,引用这个DLL在新的工程里面,然后,在你的页面代码里加入如下代码:

 

<%@ Register Assambly=”myControls” Namespace=”myControls” TagPrefix=”MC” %>

 

一旦在工程里添加DLL引用后,工程会自动COPY这个DLL到BIN目录里面,在你的VS智能感知里面会出现类如MC:DateEditBox,在后台代码里面,你可以看到控件的属性值。

 

总结:

你还可以添加更多的功能在这个控件里,但是这里只是显示最基本的控件需要代码。创建新的子控件,设置它们的ID值,添加到控件集合里,最后呈现出来。至此一个复合控件就完成了。之后,在添加更多的事件,属性和方法等,让你的控件看起来更酷一些。

P.S.大家可以注意到在这段代码里面有个EnsureChildControls()方法,在作者的原文中没有相关的说明,非常感谢wangzhe.king在这里提出问题,我想大多数朋友都不太清楚,这个方法,在此说明一下:

这个方法在检测当前ChildControlsCreated的值,如果是FALSE的话,那么就调用这个方法。ASP.NET调用这个方法,以保证子控件已经构建完毕。在大多数情况下,自定义服务器控件开发者不必重写这个方法。这个方法大多数用在属性器里面,因为在设置或得到属性值以前,你要检测子控件是否已经构建了。

官方详细解说,点此查看!
译自:CodeGuru 原文地址

转载于:https://www.cnblogs.com/lgp/archive/2006/10/23/537007.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值