動態創建GridView的列(第二部分)

翻譯]動態創建GridView的列(第二部分)

原文發佈日期:2006.11.24
作者:Bipin Joshi
翻譯:webabcd


介紹
第一部分(譯者注:第一部分的中文在這裏)你學到了如何動態的創建BoundField和CommandField。但是常常你構造的那些列滿足不了要求,所以需要使用TemplateField。例:如果要創建一個產品目錄,當然可以使用普通的列表式的佈局,但是如果你想每一條記錄都有高度自定義格式,這就不合適了。TemplateField遇到這種情形可以手動修改格式。本文將圖解說明如何動態的創建TemplateField。你將學到如下兩種技術:

    ·使用LoadTemplate()方法
    ·創建自定義模板列


使用LoadTemplate()方法增加TemplateField
爲了本例的實現,你需要在Visutal Studio新建一個websit。拖拽一個GridView和SqlDataSource到默認頁。我們將通過編碼設置這些控件的一些列屬性。首先,我們將使用LoadTemplate()方法來增加一個TemplateField。LoadTemplate()方法對於頁面上所有的模板控件來說都是可用的。它通過虛擬路徑加載模板。LoadTemplate()的返回值是一個實現了ITemplate接口的對象。

在我們的例子裏我們將在用戶控件裏創建一個模板。在website裏新建一個名爲ItemTemplate.ascx的用戶控件。其關鍵代碼如下。
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ItemTemplate.ascx.cs" Inherits="ItemTemplate" %>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("EmployeeID") %>'></asp:Label>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("FirstName") %>'></asp:Label>
<asp:Label ID="Label3" runat="server" Text='<%# Eval("LastName") %>'></asp:Label>

仔細看一下上面的標記。它包含了3個Label控件。每個Label控件的Text屬性分別綁定了Employees表的EmployeeID,FirstName和LastName列。Eval()表達式是asp.net中的一種數據綁定方法,它使用列的名字去綁定。這個用戶控件稍後將在我們的ItemTemplate中使用。

現在打開默認webform的代碼編輯窗口,其Page_Load事件中的關鍵代碼如下。
protected void Page_Load(object sender, EventArgs e)
{
    SqlDataSource1.ConnectionString 
= @"data source=.;initial catalog=northwind;integrated security=true";
    SqlDataSource1.SelectCommand 
= "select employeeID,FirstName,LastName from employees";

    
if (!IsPostBack)
    
{
        GridView1.DataSourceID 
= "SqlDataSource1";
        GridView1.AutoGenerateColumns 
= false;

        TemplateField tf1 
= new TemplateField();
        tf1.ItemTemplate
=LoadTemplate("ItemTemplate.ascx");
        GridView1.Columns.Add(tf1);
    }

}

這段代碼指出了SQL數據源控件的ConnectionString屬性是連到Northwind數據庫的。其SelectCommand屬性指定爲一段select查詢語句,它從Employees表中檢索出EmployeeID,FirstName和LastName列。然後設置了GridView的DataSourceID屬性爲該數據源控件的ID。同時AutoGenerateColumns屬性設置成false以便動態的增加列。再接下來的那幾行代碼是非常重要的。首先實例化一個TemplateField類,該類是可以呈現爲一個GridView的TemplateColumn。TemplateField類的ItemTemplate屬性設置爲LoadTemplate()方法的返回值。LoadTemplate()方法使用虛擬路徑來加載模板(在我們的例子裏模板文件爲ItemTemplate.ascx)。然後把這個TemplateField增加到GridView控件的列集合中。

在你的瀏覽器中運行這個webform將會如下顯示。


注意如何應用用戶控件中指定的模板。同時我們看到標題是空的,因爲沒有指定HeaderTemplate。你可以指定它或者關閉它。


使用自定義模板類增加TemplateField
現在你已經知道了如何使用LoadTemplate()方法,接下來讓我們來看看如何使用另一種方法。在最後的例子中你學到了用LoadTemplate()方法返回一個實現了Itemplate接口的對象。你自己也可以創建這樣一個實現了Itemplate接口的類並直接使用它,從而代替LoadTemplate()方法。

我們在App_Code文件夾內新建一個名爲MyTemplate的類。其關鍵代碼如下。
public class MyTemplate:ITemplate
{
    
private string colname; 

    
public MyTemplate(string colname)
    
{
        
this.colname = colname; 
    }
    

    
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;        
        GridViewRow container 
= (GridViewRow)l.NamingContainer;        
        l.Text 
= ((DataRowView)container.DataItem)[colname].ToString();    
    }

}

這段代碼創建了一個實現了Itemplate接口的名爲MyTemplate的類。這個接口只包含一個你必須實現的方法 - InstantiateIn()。這段代碼聲明瞭一個變量用來保存被顯示的列的名稱,該名稱在類的構造函數中設置,然後實現InstantiateIn()方法。該方法的參數爲一個容器類型或父控件類型的控件的對象。在這裏,我們創建了一個LiteralControl和一個DataBinding事件(OnDataBinding)。這個事件在容器控件調用DataBind()方法時發生。然後把這個LiteralControl加到容器控件的控件集合中。

OnDataBinding()事件所作的工作就是把所需的數據綁定到LiteralControl。給容器控件加上NamingContainer屬性,然後提取出一個Row。最後,LiteralControl的Text屬性被設置爲構造函數所指出的列的在數據庫中所存儲的值。這樣,我們的自定義模板類就完成了。

在website裏新建一個webform。像以前一樣拖拽一個GridView和SqlDataSouce到頁上。其Page_Load事件中的代碼如下。
protected void Page_Load(object sender, EventArgs e)
{
    SqlDataSource1.ConnectionString 
= @"data source=.;initial catalog= northwind;integratedsecurity=true";
    SqlDataSource1.SelectCommand 
= "select employeeID,FirstName,LastName from employees";

    
if (!IsPostBack)
    
{
        GridView1.DataSourceID 
= "SqlDataSource1";
        GridView1.AutoGenerateColumns 
= false;

        TemplateField tf1 
= new TemplateField();
        MyTemplate t1 
= new MyTemplate("FirstName");
        tf1.HeaderText 
= "First Name";
        tf1.ItemTemplate 
= t1;

        TemplateField tf2 
= new TemplateField();
        MyTemplate t2 
= new MyTemplate("LastName");
        tf2.HeaderText 
= "Last Name";
        tf2.ItemTemplate 
= t2;

        GridView1.Columns.Add(tf1);
        GridView1.Columns.Add(tf2);
    }

}

這段代碼如從前一樣設置了GridView和SqlDataSource的屬性。注意代碼中加粗的部分(譯者注:就是代碼的中下部份),它是用來創建TemplateField類的實體的。這次TemplateField的ItemTemplate屬性被設置成了實例化的MyTemplate類。列的名稱 - FirstName和LastName被傳到了構造函數中。TemplateField被增加到了GridView的列集合中。

運行上面的webform將如下顯示。


本文結束!祝編碼愉快。


作者:Bipin Joshi
Email:http://www.dotnetbips.com/contact.aspx
簡介:Bipin Joshi是DotNetBips.com的管理員。他是http://www.binaryintellect.com/的發起人,這個公司提供.NET framwork的培訓和諮詢服務。他在印度孟買爲開發者提供培訓。他也是微軟的MVP(ASP.Net)和ASPInsiders的會員。  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章