Asp.Net教程,WinForm教程,Asp.Net MVC,vs2008教程,vs2010教程,Silverlight技术,源码下载,Asp.Net视频教程
全站热门标签
vs2010 Silverlight 存储过程 水晶报表 ADO.NET JavaScript LINQ AjaxPro DataGridView 面向对象 Extjs GridView XML DevExpress HTML教程 Oracle jQuery 分页 GDI+ Visual C++2010 MySQL Office2010 WPF MVC Dojo WCF4.0 VB.NET Sql2005 textbox cookie WCF WinForm Discuz!NT SQL经典语句 T-SQL checkbox ASPxGridView F# asp.net SQL VS2008新特性 DropDownList Access TreeView Ajax VS2008 页面执行时间 Flex 字符串 回调 VB2005 DataSet C#时间 ASP.NET性能优化 用户在线检测 动画
尚未分类 LINQ教程 Enterprise技术 性能优化/调试 水晶报表与打印 安全与加密 图形图像 文件处理 基础教程 Web Services 内置对象 控件示例 正则表达式\采集 ADO.NET 缓存\泛型\线程 XML技术 Url重写\静态页 vs2008综合教程
当前位置: 主页 > ASP.NET教程 > 尚未分类 >

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

时间:2010-07-15 22:47来源:未知 作者:admin 点击:
 


 


表6-1 ASP.NET控件的执行生命周期

在这里,控件设计利用了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}><&nbsp;Previous</a>";
    private const string LINK_MORE = "<a href=?page={0}>More&nbsp;></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;
        }
    }
}
当设置的value对象值不为IList类型时,set访问器就将捕获异常,然后将dataSource字段设置为null。

由于我们改写了DataSource属性,因而改写Repeater类的OnDataBinding()方法也就势在必行。此外,CustomGrid还提供了分页的功能,我们也需要实现分页的相关操作。与DataSource属性不同,Repeater类的OnDataBinding()方法实际上是继承和改写了Control基类的OnDataBinding()虚方法,而我们又在此基础上改写了Repeater类的OnDataBinding()方法:

override protected void OnDataBinding(EventArgs e) {

    //Work out which items we want to render to the page
    int start = CurrentPageIndex * pageSize;
    int size = Math.Min(pageSize, ItemCount - start);

    IList page = new ArrayList();
    //Add the relevant items from the datasource
    for (int i = 0; i < size; i++)
        page.Add(dataSource[start + i]);

    //set the base objects datasource
    base.DataSource = page;
    base.OnDataBinding(e);
}
此外,CustomGrid控件类还增加了许多属于自己的属性和方法,例如PageSize、PageCount属性以及SetPage()方法等。正是因为ASP.NET控件引入了Composite模式与Template Method模式,当我们在自定义控件时,就可以通过继承与改写的方式来完成控件的设计。自定义ASP.NET控件一方面可以根据系统的需求实现特定的功能,也能够最大限度地实现对象的重用,既可以减少编码量,同时也有利于未来对程序的扩展与修改。
在PetShop 4.0中,除了自定义了上述WebControl控件的子控件外,最主要的还是利用了用户控件。在Controls文件夹下,一共定义了11个用户控件,内容涵盖客户地址信息、信用卡信息、购物车信息、期望列表(Wish List)信息以及导航信息、搜索结果信息等。它们相当于是一些组合控件,除了包含了子控件的方法和属性外,也定义了一些必要的UI实现逻辑。以ShoppingCartControl用户控件为例,它会在该控件被呈现(Render)之前,做一些数据准备工作,获取购物车数据,并作为数据源绑定到其下的Repeater控件:

public partial class ShoppingCartControl : System.Web.UI.UserControl
      
    protected void Page_PreRender(object sender, EventArgs e) {
        if (!IsPostBack) {
            BindCart();               
        }
    }
    private void BindCart() {

        ICollection<CartItemInfo> cart = Profile.ShoppingCart.CartItems;
        if (cart.Count > 0) {
            repShoppingCart.DataSource = cart;
            repShoppingCart.DataBind();
            PrintTotal();
            plhTotal.Visible = true;
        }
        else {
            repShoppingCart.Visible = false;
            plhTotal.Visible = false;
            lblMsg.Text = "Your cart is empty.";
        }
    }
在ShoppingCart页面下,我们可以加入该用户控件,如下所示:

<PetShopControl:shoppingcartcontrol id="ShoppingCartControl1" runat="server"></PetShopControl:shoppingcartcontrol>
由于ShoppingCartControl用户控件已经实现了用于呈现购物车数据的逻辑,那么在ShoppingCart.aspx.cs中,就可以不用负责这些逻辑,在充分完成对象重用的过程中,同时又达到了职责分离的目的。用户控件的设计者与页面设计者可以互不干扰,分头完成自己的设计。特别是对于页面设计者而言,他可以是单一的UI设计人员角色,仅需要关注用户界面是否美观与友好,对于表示层中对领域对象的调用与操作就可以不必理会,整个页面的代码也显得结构清晰、逻辑清楚,无疑也“干净”了不少。

 

(责任编辑:admin)
Tags:petshop4.0
责任编辑:admin
返回顶部
------分隔线----------------------------
推荐内容
骆驼户外男 真皮磨砂日常休闲鞋 低帮 2011秋冬新款 专柜正品特价 骆驼户外男 真皮磨砂日常休闲鞋 低帮 2011秋冬新款 专柜正品特价