以下通過一個ASP.NET的Demo,希望能使您加深對多態的理解。
現在的需求是這樣子(當然該需求 是借助於最近的項目中碰到的問題),在該系統中的流程管理中,有兩個頁面,一個顯示的是我本人發起的審 批列表,另一個是等待我進行審批的列表,他們的查詢以及列表顯示和查看審批歷史等均一致,唯一不同的是 待審批還有一個可執行審批動作的一列,但是不同的人或者在不同的應用(我在這裡假設該系統是有多個應用 的復雜系統)裡面獲取到列表的列是不一樣的,所以需要使用動態列,當然這些數據來源我在這裡不贅述,為 便於舉例我也不會去使用到數據庫,您可以構造一個類,包含一個屬性為列的集合,一個屬性為數據集即可, 當然下面的例子均會涉及。
我的環境為Windows 7+ Visual Studio 2010,我創建了一個 WebApplication,名為WebApplication3,為了頁面好看點,我將不會選擇空Web Application。添加兩個aspx 頁面(MyApprovals和ToApprovals),並在母版頁的導航添加鏈接(如果你沒有母版頁可以跳過此步驟直接創 建頁面即可)
<asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" EnableViewState="false" IncludeStyleBlock="false" Orientation="Horizontal"> <Items> <asp:MenuItem NavigateUrl="~/Default.aspx" Text="主頁"/> <asp:MenuItem NavigateUrl="~/MyApprovals.aspx" Text="我的申請"/> <asp:MenuItem NavigateUrl="~/ToApprovals.aspx" Text="待我審批"/> <asp:MenuItem NavigateUrl="~/About.aspx" Text="關於"/> </Items> </asp:Menu>
頁面代碼很簡單,MyApprovals的頁面代碼如下:
<p> <asp:TextBox ID="txtKey" runat="server"></asp:TextBox> <asp:Button ID="btnSearch" runat="server" Text="Button" onclick="btnSearch_Click" /> <asp:Label ID="lblMsg" runat="server" ForeColor="Red"></asp:Label> </p> <p> <asp:GridView ID="gvApprovals" runat="server"> </asp:GridView> </p>
ToApprovals的頁面代碼後面再貼出來。
創建他們的後台代碼的基類名為 ApprovalBasePage,我們在實際開發中可能還有一個更BasePage之類的基類,這時ApprovalBasePage就應繼承 於BasePage,
View Code public class ApprovalBasePage : BasePage { /// <summary> /// 0為我發起審批的頁面,1為待審批的頁面,可由子類去確定類型 /// </summary> protected virtual int PageType { get { return 0; } } private ApprovalData dataSource; /// <summary> /// 獲取數據源 /// </summary> ApprovalData DataSource { get { if (this.dataSource == null) { this.dataSource = ApprovalData.GetData(this.PageType); } return this.dataSource; } } /// <summary> /// 進行數據綁定,參數僅作為示范作用, /// 因為綁定時可能會與用戶有些交互,這些交互很可能不相同,因而留給子類去重寫 /// 但是本例中他們的數據綁定幾乎是一樣的 /// </summary> protected virtual void BindData(string key = ""){ } /// <summary> /// 將數據轉化為DataTable,便於綁定 /// </summary> /// <returns></returns> protected DataTable DataToTable() { DataTable dt = new DataTable(); if (this.DataSource == null) { return null; } foreach (var item in this.DataSource.HeadList) { dt.Columns.Add(item, typeof(string)); } DataRow dr = null; int colIndex = 0; foreach (var item in this.DataSource.ContentList) { dr = dt.NewRow(); colIndex = 0; foreach (var itemCol in item) { dr[colIndex++] = itemCol; if (colIndex >= dt.Columns.Count) { //雖然提供該接口的保證數據肯定是與列數對應的 //但我還是盡量保證數據異常時程序不會報錯 break; } } dt.Rows.Add(dr); } return dt; } #region event 兩個頁面的共同事件都放進這裡來了 protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { BindData(); } } protected void btnSearch_Click(object sender, EventArgs e) { BindData(); } #endregion }