有的時候我們需要邦定很復雜的DataGrid,我們知道DataGrid,DataList等控件都有Template列,我們可以通過動態的邦定模版列來實現,復雜邏輯的邦定。由於Page繼承TemplateControl,所以在Page對象裡面就可以使用TemplateControl類裡面的方法LoadTemplate,我們可以利用這個方法加載指定路徑用戶控件來實現豐富的表示(順便提一下還有一個LoadControl的方法和LoadTemplate有相同的參數類型,也就是說我們可以利用LoadControl方法動態的加載用戶控件,可以實現自定義的用戶界面,將頁面元素分成一些小的用戶控件可以根據用戶的定義來加載),我們還可以實現Itemplate接口實現摸版列的動態邦定。
1、使用LoadTemplate實現:
下面我們看一個例子,我們建立一個ASP.NET的Web應用程序,在添加一個ascx的用戶控件叫webusercontrol1.ascx如下所示,該用戶控件裡面只有一個Label控件用來邦定一個Lastname字段:
<%@ Control Language="C#" %>
<asp:label ID="label1" Runat="server" text='<%# Databinder.Eval(((DataGridItem)Container).DataItem,"lastname")%>'></asp:label>
接下來我們將要創建一個DataGrid控件DataGrid1,我們將在Page_Load事件裡面添加如下的代碼:
string connstr = @"Integrated Security=SSPI;User ID=sa;Initial Catalog=Northwind;Data Source=MyServer/NetSDK";
SqlConnection cnn=new SqlConnection(connstr);
SqlDataAdapter da=new SqlDataAdapter("select * from employees", cnn);
DataSet ds=new DataSet();
da.Fill(ds, "employees");
ITemplate temp= Page.LoadTemplate("webusercontrol1.ascx");
TemplateColumn tc=new TemplateColumn();
tc.HeaderText = "Last Name";
tc.ItemTemplate = temp;
DataGrid1.Columns.Add(tc);
DataGrid1.DataSource = ds;
DataGrid1.DataMember = "employees";
DataGrid1.DataBind();
先面我們分析一下上面的代碼,我們使用一個SQL Server裡面自帶的示例數據庫Northwind。我們將得到所有的員工信息,然後填充數據集,然後我們聲明一個Itemplate類型的對象temp用來裝載邦定的用戶控件。我們在聲明一個TemplateColumn來動態創建一個模版列,接下來我們給該模版列添加信息,其中包括HeaderText等等,由於我們將要邦定的事ItemTemplate所以我們將剛才裝載的temp賦值給該模版列的ItemTemplate對象,最後我們就將新的摸版列添加到DataGrid裡面並邦定數據。
注意到上面過程,我們的用戶控件裡面有一個數據邦定的Label這個很重要,只有這樣我們才能實現數據邦定的功能,否則就是顯示一個有著相同信息的列。
2、使用Itemplate實現:
上面我們使用LoadTemplate實現動態摸版列的邦定,接下來我們將使用Itemplate接口來實現。Itemplate接口有一個方法InstantiateIn(Control container)。這個方法必須指定摸版列的父親控件。下面的代碼將會實現Itemplate接口,我們使用下面的代碼創建一個新的類:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
namespace DynamicDataGridTemplates{
public class CTemplateColumn:ITemplate{
private string colname;
public CTemplateColumn(string cname){
colname=cname;
}
//為了使用接口必須實現的方法
public void InstantiateIn(Control container) {
LiteralControl l = new LiteralControl();
l.DataBinding += new EventHandler(this.OnDataBinding);
container.Controls.Add(l);
}
public void OnDataBinding(object sender, EventArgs e){
LiteralControl l = (LiteralControl) sender;
DataGridItem container = (DataGridItem) l.NamingContainer;
l.Text = ((DataRowView) container.DataItem)[colname].ToString();
}
}
}
在構造函數裡面我們為邦定列指定了列名。我們使用InstantiateIn創建了一個LiteralControl控件l,同時我們為這個控件添加事件邦定事件,這樣我們可以在邦定DataGrid的時候可以處理邦定這個控件,同時為了實現事件邦定事件,我們還編寫了事件處理函數OnDataBinding,在這裡我們將用指定的列邦定數據。
接下來我們將我們的自定義的摸版列動態的添加到DataGrid裡面,如下的代碼是Page_Load裡面的:
DataGrid datagrid1=new DataGrid();
TemplateColumn tc1=new TemplateColumn();
tc1.ItemTemplate=new CTemplateColumn("lastname");
tc1.HeaderText="Last Name";
datagrid1.Columns.Add(tc1);
Page.Controls[1].Controls.Add(datagrid1);
string connstr = @"Integrated Security=SSPI;User ID=sa;Initial
Catalog=Northwind;Data Source=MyServer/NetSDK";
SqlConnection cnn=new SqlConnection(connstr);
SqlDataAdapter da=new SqlDataAdapter("select * from employees", cnn)
DataSet ds=new DataSet();
da.Fill(ds, "employees");
datagrid1.DataSource = ds;
datagrid1.DataMember = "employees";
datagrid1.DataBind();
首先我們New一個DataGrid出來,然後聲明一個模版列tc1,在設置tc1的ItemTemplate為我們自定一個模版列(不要忘了用列名這個參數),然後指定這個模版列的其他信息,最後利用DataSet邦定數據(不要忘了將控件添加到它的父控件裡面,比如:datagrid1.Columns.Add(tc1);)。
上面介紹了兩種動態邦定模版列的方法,希望可以對初學者有所幫助,其實這裡的方法是很簡單的,我想這裡最關鍵的問題是如何理解面向對象,希望通過這篇文章的描述初學者可以對面向對象有更好的理解,我們這裡使用了接口的繼承以及父類子類之間的關系,通過使用接口的繼承我們可以制作一個模版列的工廠可以使用同一種模式產生不同的模版列,因為我們使用的是接口(詳細信息請見《設計模式》)。