以下通過一個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
}