一、簡介
從ASP.NET 2.0起引入了一批新的功能強大的視圖控制項,例如Gridview、FormView和DetailsView等等。通過和資料來源控制項的簡單結合,在許多情況下,僅需要簡單的配置方式就可以開發出功能強大的應用程式。但遺憾的是,Gridview控制項中並沒有提供像在FormView和DetailsView控制項中那樣直接插入新記錄操作的支援。圖1給出了典型的使用控制項展示資料庫資料的情形。
圖1 使用GridView控制項展示VS2005樣本資料庫Address表格中的資料
熟悉Gridview控制項使用的朋友都知道,圖1中一切都齊了,只差一個Insert操作的預設支援。我現在使用的是ASP.NET 3.5,結果一樣,仍然沒有直接提供對於插入操作的配置支援。
二、解決方案
其實,答案還是有的,這要求對於Gridview控制項有更進一步的瞭解。我們知道Gridview為方便開發人員定製編程提供了大量的模板支援。根據插入操作的一般實現介面,我們可以利用Gridview的footer的模版功能,實現在Gridview控制項的最後一行,提供一個空白行給使用者輸入要輸入的記錄,從而間接地實現Gridview控制項對於插入操作的支援。
三、執行個體展示
(一)建立樣本網站並建立資料庫關聯
啟動Visual Studio 2005/2008並選擇“ASP.NET Web Site”模板新建立一個樣本網站GridViewExt。在預設頁面Default.aspx中拖入一個GridView控制項。然後,點擊GridView控制項右上方的智能感知提示按鈕,為此控制項配置一個SqlDataSource類型的資料來源控制項SqlDataSource1。並且,通過簡單的嚮導配置之後,使資料來源控制項SqlDataSource1建立與樣本資料庫Depart.mdf的關聯,並進一步關聯到其中的DepartInfo表格上。
【提示】為了簡化起見,樣本資料庫Depart.mdf中僅包含了一個表格DepartInfo,而且其架構也十分簡單(其中欄位DepartID為主關鍵字),如2所示:
最後產生的資料來源控制項SqlDataSource1配置參數(經一定修改)如下所示:
<asp:SqlDataSource ID="SqlDataSource1" runat="[url=javascript:;]server[/url]"
ConnectionString="<%$ ConnectionStrings:DepartConnectionString %>"
SelectCommand="SELECT DepartID, DepartName FROM DepartInfo"
DeleteCommand="Delete from DepartInfo where DepartID=@DepartID"
InsertC
>
<DeleteParameters>
<asp:Parameter Name="DepartID" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="DepartID" Type="Int32" />
<asp:Parameter Name="DepartName" Type="String" />
</InsertParameters>
</asp:SqlDataSource>
(二)修改頁面Default.aspx布局
我們的打算是,在讓使用者進行選擇,當使用者需要新增一記錄時,便點擊“添加”按鈕,之後在Gridview的最後一行裡,顯示一個空白行,讓使用者按欄位進行輸入。當使用者決定不輸入新空白記錄時,可以按"隱藏"按鈕返回,該空白行消失。
要實現以上目的,我們可以充分利用Gridview的footer的模版功能進行自訂,因為表格中僅有一個可編輯列DepartName;所以,我們只需要在此列的footer模版中,定義如下(注意其中加粗部分):
<asp:Button ID="outAdd" runat="Server" Text="添加新記錄" nclick="outAdd_Click" />
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
AllowSorting="True" AutoGenerateColumns="False" CellPadding="4"ShowFooter =" false"
DataSourceID="SqlDataSource1" ForeColor="#333333" GridLines="None"DataKeyNames="DepartID">
<FooterStyle. BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<RowStyle. BackC0" numbertype="1" negative="False" hasspace="False" sourcevalue="7" unitname="F" w:st="on">7F6F3" ForeColor="#333333" />
<Columns>
<asp:TemplateField ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True"
CommandName="Update" Text="Update"></asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
CommandName="Cancel" Text="Cancel"></asp:LinkButton>
</EditItemTemplate>
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False"
CommandName="Edit" Text="Edit"></asp:LinkButton>
</ItemTemplate>
<FooterTemplate>
<asp:Button ID="btnAdd" Runat="server" Text="Add" nClick="btnAdd_Click" />
<asp:Button ID="btnCancel" Runat="server" Text="Hide" nClick="btnCancel_Click" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
CommandName="Select" Text="Select"></asp:LinkButton>
</ItemTemplate>
<ItemTemplate>
<asp:LinkButton ID="LinkButton3" runat="server" CausesValidation="true"
CommandName="Delete" Text="Delete"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="DepartID" HeaderText="DepartID"
InsertVisible="False" ReadOnly="True" SortExpression="DepartID" />
<asp:TemplateField HeaderText="DepartName" SortExpression="DepartName">
<EditItemTemplate>
<asp:TextBox ID="DepartNameTextBox" runat="server" Text='<%# Bind("DepartName") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("DepartName") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox ID="DepartNameBox" Runat="server"></asp:TextBox>
</FooterTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle. BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<SelectedRowStyle. BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle. BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<EditRowStyle. BackColor="#999999" />
<AlternatingRowStyle. BackColor="White" ForeColor="#284775" />
</asp:GridView>
首先注意的是,在Gridview控制項之前添加了一個ASP.NET按鈕“outAdd”,用於控制項是否顯示Gridview控制項的<foottemplate>模板內容。顯然,在頁面啟動開始時這個模板是隱藏的。因此,這個按鈕的Click事件代碼(位於檔案Default.aspx.cx中)相當簡單,如下所示:
protected void outAdd_Click(object sender, EventArgs e)
{
GridView1.ShowFooter = true;
}
接下來是Gridview的有關的標記代碼。可以看到,在DepartName列的<foottemplate>中提供了DepartNameBox文字框以供使用者輸入(因為本例中的這個欄位僅是簡單的文字欄位,對於其它類型欄位的情況,需要建立相應的ASP.NET控制項進行操作)。
另外,請注意在第一列的<FooterTemplate>中我們添加了Add和Hide兩個按鈕,它們的事件代碼如下:
<script. runat="server">
void btnCancel_Click(object sender, EventArgs e)
{
GridView1.ShowFooter = false;
}
void btnAdd_Click(object sender, EventArgs e)
{
TextBox t1 = GridView1.FooterRow.FindControl("DepartNameBox") as TextBox;
SqlDataSource1.InsertParameters["DepartName"].DefaultValue = t1.Text;
SqlDataSource1.Insert();
}
其中的Hide按鈕的事件,用來取消顯示Gridview的footer模版,因此設定showfooter屬性為false,而通過點擊按鈕Add則可以將新增的記錄插入(添加)到資料庫表格中去。
而Add按鈕,是當使用者決定新增記錄時點選的,此時將設定showfooter屬性為true,以顯示各列的foottemplate,從而達到顯示新的一個空白行的目的。
特別值得注意的是,在這裡你必須以內聯方式把按鈕“Add”與“Hide”的Click事件處理器函數放置於ASPX檔案之中,而不能放到代碼檔案Default.aspx.cs中;否則,會出現3所示的編譯錯誤。
圖3 把按鈕“Add”與“Hide”的Click事件處理器函數放置於代碼檔案Default.aspx.cs中導致的編譯錯誤提示另外,在GridView1的屬性聲明中必須指定DataKeyNames="DepartID";否則,在運行時如果點擊“Delete”或“Update”連結會出現“經典”的錯誤提示,4所示。
圖4 未指定GridView的DataKeyNames導致的錯誤提示
四、觀察運行結果
按F5運行上面的樣本頁面DEFAULT.ASPX,一切順利的話,你會觀察到5所示的初始快照集。
圖5 樣本頁面初始快照集然後,點擊“添加新記錄”按鈕,將出現6所示快照。
圖6 為GRIDVIEW控制項添加“插入”功能的運行樣本快照
很顯然,在輸入部門名稱後點擊“Add”可以把新的部門加入到資料庫表格中,而點擊“Hide”按鈕則可以隱藏這個頁尾的顯示。
五、小結
ASP.NET 2.0引入的Gridview控制項功能相當強大,但是也存在一定的不足。本文中展示的僅僅是其中之一,而且也僅展示了為Gridview控制項提示插入功能的一種方法。
最後注意,雖然本文樣本右VS2008下調試通過,但根據我的經驗,在VS2005的ASP.NET 2.0環境下也應該沒有問題。