petshop4.0 详解之六(PetShop表示层设计)(2)

petshop4.0 详解之六(PetShop表示层设计)(2)
2007-09-12 16:14

在这里,控件设计利用了Template Method模式,Control基类提供了大部分protected虚方法,留待其子类改写其方法。以PetShop 4.0为例,就定义了两个ASP.NET控件,它们都属于System.Web.UI.WebControls.WebControl的子类。其中,CustomList控件派生自System.Web.UI.WebControls.DataList,CustomGrid控件则派生自System.Web.UI.WebControls.Repeater。

由于这两个控件都改变了其父类控件的呈现方式,故而,我们可以通过重写父类的Render虚方法,完成控件的自定义。例如CustomGrid控件:

public class CustomGrid : Repeater…
// Static constants
     protected const string HTML1 = " <table cellpadding=0
cellspacing = 0 >< tr >< td colspan = 2 > " ;
     protected const string HTML2 = " </td></tr><tr><td class=paging align=left> " ;
    
protected const string HTML3 = " </td><td align=right class=paging> " ;
    
protected const string HTML4 = " </td></tr></table> " ;
    
private static readonly Regex RX = new Regex( @" ^&page=/d+ " ,
RegexOptions.Compiled);
    
private const string LINK_PREV = " <a href=?page={0}>&#060;&nbsp;Previous</a> " ;
    
private const string LINK_MORE = " <a href=?page={0}>More&nbsp;&#062;</a> " ;
private const string KEY_PAGE = " page " ;
    
private const string COMMA = " ? " ;
    
private const string AMP = " & " ;

override protected void Render(HtmlTextWriter writer) {

        
//Check there is some data attached
        if (ItemCount == 0) {
             writer.Write(emptyText);
            
return;
         }

        
//Mask the query
        string query = Context.Request.Url.Query.Replace(COMMA, AMP);
         query
= RX.Replace(query, string.Empty);
        
// Write out the first part of the control, the table header
         writer.Write(HTML1);
        
// Call the inherited method
        base.Render(writer);
        
// Write out a table row closure
         writer.Write(HTML2);
        
//Determin whether next and previous buttons are required
        
//Previous button?
        if (currentPageIndex > 0)
             writer.Write(
string.Format(LINK_PREV, (currentPageIndex - 1) + query));
        
//Close the table data tag
         writer.Write(HTML3);

        
//Next button?
        if (currentPageIndex < PageCount)
             writer.Write(
string.Format(LINK_MORE, (currentPageIndex + 1) + query));

        
//Close the table
         writer.Write(HTML4);
     }

由于CustomGrid继承自Repeater控件,因而它同时还继承了Repeater的DataSource属性,这是一个虚属性,它默认的set访问器属性如下:

public virtual object DataSource
{
      
get  {… }
      
set
      
{
            
if (((value != null) && !(value is IListSource)) && !(value is IEnumerable))
            
{
                  
throw new ArgumentException(SR.GetString("Invalid_DataSource_Type", new object[] { this.ID }));
             }

            
this.dataSource = value;
            
this.OnDataPropertyChanged();
       }

}

对于CustomGrid而言,DataSource属性有着不同的设置行为,因而在定义CustomGrid控件的时候,需要改写DataSource虚属性,如下所示:

private IList dataSource;
private int itemCount;

override public object DataSource {
    
set {
    
//This try catch block is to avoid issues with the VS.NET designer
        
//The designer will try and bind a datasource which does not derive from ILIST
        try {
             dataSource
= (IList)value;
             ItemCount
= dataSource.Count;
         }

        
catch {
             dataSource
= null;
             ItemCount
= 0;
         }

     }

}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值