Asp.Net中DataGrid的模版列(TemplateColumn)內容控制簡單方法。

最近寫了幾個asp.net的項目。其中,Asp.Net的控件DataGrid使用的最多了,前幾天需要一個功能,我研究了很長時間,發現一個方法,應該是最簡單的實現。現表述如下。

DataGrid的html定義很簡單,如下
None.gif<Asp:DataGrid ID="myDatagrid" runat="server" datakeyfield="fID" AutoGenerateColumns="False">
None.gif  
<Columns>
None.gif    
<Asp:TemplateColumn itemstyle-width=".." ..>
None.gif        
<ItemTemplate>
None.gif            dot.gif.
None.gif        
</ItemTemplate>
None.gif    
</Asp:TemplateColumn>
None.gif  
</Columns>
None.gif
</Asp:DataGrid>

功能的要求是在 ItemTemplate中,有可能是一個綁定數據源的:
<a href="...">...</a>
鏈接代碼,也有可能是一個
<span>...</span>
顯示文本代碼,而判斷的根據是綁定到DataGrid中數據源的DataTable中每行的某一特定列的內容。

說白了,功能就是DataGrid在綁定數據生成行的時候,判斷數據源DataTable每行DataRow中一個字段的內容,這個字段類型是bool類型,如果爲true,則這個列顯示的是<a href="...">...</a>鏈接,而如果是false,則顯示<span>...</span>文本。而顯示的鏈接內指向的地址必須執行數據綁定。就是這個DataGrid的列有的行要數據綁定,有的行不要數據綁定。

功能需求分析到這裏,那麼現在該思考如何實現了。

我當時瞭解需求後,馬上反應出來,使用DataGrid自帶的BoundColumn、HyperLinkColumn肯定是不行的。而且,使用TemplateColumn也有麻煩。他只能放一些固定的控件,如html控件或服務器控件等。後來我沒有辦法了,準備繼承ITemplate接口自己開發一個模版列。後來又覺得麻煩。因爲綁定的時候需要一個類似於BoundColumn功能的綁定數據源內容的東西。後來我發現了這個方法。

在查看.Net Framework SDK 文檔的時候,我發現在<Asp:TemplateColumn>中的<ItemTemplate>中可以放類似於
ExpandedBlockStart.gif<%# DataBinder.Eval(Container.DataItem, "fID"%>
這樣的數據綁定代碼,我就想是否可以再加入代碼呢

我做了一個試驗,試驗結果發現上面的代碼(包括前面和後面的<% %>符號)輸出的實際上是一個object對象,然後DataGrid顯示的時候把它轉換成字符串。後來我就想,是否可以前面再加入代碼,調用這個頁面的後臺代碼中的方法。

我們都知道,在asp.net1.1中,一個名稱爲aaa.aspx的asp.net頁在asp.net內部處理時是一個名叫ASP.aaa_aspx的類,這個類繼承它的後臺代碼aaa.aspx.cs中的類,這個類繼承System.Web.UI.Page類,從而實現需要的功能。這就是說,在asp.net 1.1中,我們在.aspx中的以<% %> 包含的代碼可以調用後臺cs類中的以public 和protected生命的任何方法。

這就好辦了,既然從上面的數據綁定代碼可以獲取主鍵內容(是個字符串),那麼我可以在後臺寫一個方法,這個方法有一個字符串參數,返回的也是字符串。這個返回的字符串就是顯示在列中的內容。

首先說一下綁定表的內容,如下
列名 類型 用途
fID System.String 表主鍵
hasSub System.Boolean 判斷的依據
contentUrl System.String 鏈接的地址

然後是後臺代碼中C#代碼
None.gifprotected string GetDGColumn(string id)
ExpandedBlockStart.gif
{
InBlock.gif    
// 從數據源獲取DataTable內容略
InBlock.gif
    DataTable dt = dot.gif.;
InBlock.gif    
// 定義DataTable的主鍵列
ExpandedSubBlockStart.gif
    DataColumn[] key = {dt.Columns["fID"]};
InBlock.gif    dt.PrimaryKey 
= key;
InBlock.gif
InBlock.gif    
// 根據傳入的id開始找數據行
InBlock.gif
    DataRow row = dt.Rows.Find(id);
InBlock.gif
InBlock.gif    
// 找到後開始判斷
InBlock.gif
    if((bool)row["hasSub"])
ExpandedSubBlockStart.gif    
{
InBlock.gif        
// hasSub爲 true,表示返回<span>
InBlock.gif
        return "<span style=/"dot.gif/">內容內容</span>";
ExpandedSubBlockEnd.gif    }

InBlock.gif    
else
ExpandedSubBlockStart.gif    
{
InBlock.gif        
// hasSub列爲false,返回鏈接
InBlock.gif
        return "<a href=/"XXXX.aspx?id="+id+"/" target=/"_blank/">鏈接內容</a>";
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

然後在.aspx中的DaaGrid內這樣定義:
None.gif<Asp:DataGrid ID="myDatagrid" runat="server" datakeyfield="fID" AutoGenerateColumns="False"> 
None.gif  
<Columns> 
None.gif    
<Asp:TemplateColumn itemstyle-width=".." ..> 
None.gif        
<ItemTemplate> 
ExpandedBlockStart.gif            
<%# base.GetDGColumn((object)DataBinder.Eval(Container.DataItem, "fID")) %>
None.gif        
</ItemTemplate> 
None.gif    
</Asp:TemplateColumn> 
None.gif  
</Columns> 
None.gif
</Asp:DataGrid>
None.gif

利用了DataGrid綁定時內部使用的數據綁定方法獲取結果,然後把結果傳遞給GetDGColumn()方法,DataGrid列的內容實際上是使用的這個方法返回的字符串。


好了,一個隨心所欲生成DataGrid列內容的方法說完了,不知道大家有沒有更好的方法。
我這個方法的缺點就是生成的內容沒有辦法執行服務器提交,它無法被服務器段區分開,所以只能是使用靜態的鏈接,文本等。還有就是可以調用客戶端的js腳本。如果誰有更好的方法,如生成的鏈接按鈕的單擊事件可以被服務器端區分,請指教。如果大家有更好的方法,也請指教。我在這裏謝謝大家了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章