亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

考察DataGrid控件 Part 7

系統(tǒng) 2041 0

考察DataGrid控件 Part 7 (上)

本文英文原版:
http://aspnet.4guysfromrolla.com/articles/080702-1.aspx


導(dǎo)言:

在編輯界面里,默認(rèn)的是TextBoxes控件,不過你可以對界面進(jìn)行定制使其更具靈活性。比如,假如DataGrid控件里的某個列是True/False域,我們展現(xiàn)一對True/False單選項要比默認(rèn)的TextBoxes控件要好的多;再比如,假設(shè)一個列為某個表的外鍵(foreign key),我們提供一個DropDownList控件供用戶選擇恰當(dāng)?shù)倪x項或許是個更好的辦法。定制DataGrid的編輯界面需要額外的代碼,不過這些都比較簡單,我個人認(rèn)為,難的是理解發(fā)生在頁面背后的運行機(jī)制原理。


用EditItemTemplate定制編輯界面

為了定制DataGrid的編輯界面,我們要用到模版列(TemplateColumn)。記得在本系列文章的Part 5部分提到過,可以向DataGrid添加模版列以自定義HTML輸出效果。如果是綁定列(BoundColumn)的話,默認(rèn)的是TextBox界面。在本文,我們要用到的是一個real-world示例。在本系列的前面部分,我們看到的示例關(guān)于ASPFAQs.com上的常見問題解答。用到的是FAQ數(shù)據(jù)庫,它有一系列的數(shù)據(jù)表,其中最主要的是tblFAQ表,每一行記錄對應(yīng)一條FAQ(即常見問題解答)。其中一個列FAQCategoryID,它是數(shù)據(jù)表tblFAQCategory的一個外鍵,該數(shù)據(jù)表的每一行記錄對應(yīng)一個FAQ種類(這些種類包括Array, Appilcation Object, Email, ASP.NET, Forms等等) 。下面是這2個表的重要部分的定義:

考察DataGrid控件 Part 7
基于前6章的基礎(chǔ)知識,你應(yīng)該快速而容易的創(chuàng)建一個DataGrid來顯示每條FAQ,包括FAQ的種類名稱(注意不是integer類型的)。下面的SQL語句可以挑選出每條FAQ的種類名稱:
SELECT FAQID, F.FAQCategoryID, Name AS CategoryName, Description
FROM tblFAQ F
INNER JOIN tblFAQCategory FC ON FC.FAQCategoryID = F.FAQCategoryID

(演示頁面為 http://aspnet.4guysfromrolla.com/demos/dgExample13.aspx )

現(xiàn)在假設(shè)你想讓用戶編輯DataGrid,你可能會想,“哈哈,我已經(jīng)看完前6章,我知道怎么做了,首先添加一個EditCommandColumn!”不錯,這是正確的第一步,不過我們還要做更多的工作,因為默認(rèn)時,綁定列呈現(xiàn)的編輯界面不太理想。看一下這個演示頁面

http://aspnet.4guysfromrolla.com/demos/dgExample14.aspx ),點擊某行的Edit按鈕,你會看到什么?要是你懶得點這個演示頁面的話,下面的這個圖顯示了最終效果。

考察DataGrid控件 Part 7

我們注意到在編輯模式里,列Category已經(jīng)轉(zhuǎn)變成了默認(rèn)的TextBox。咋一看好像沒什么問題,假設(shè)某人想把編號為2的Category由Strings變?yōu)锳rrays,他只需要鍵入Arrays。然而,從各個方面考慮這并不是最優(yōu)方案。首先,Category列是數(shù)據(jù)表tblFAQCategory的外鍵,雖然你可以遍歷tblFAQCategory來查找恰當(dāng)?shù)腸ategory名稱,然后用對應(yīng)的FAQCategoryID值來更新處于編輯狀態(tài)的tblFAQ row,但這樣顯的有點凌亂。再者,假如用戶輸入有誤呢,比如將“Strings”輸入成“String”?你怎么辦呢?彈出一個錯誤消息嗎?假設(shè)用戶是有意的,那么要在tblFAQCategory里新添加一行記錄嗎?

明顯,理想情況是在Category列將TextBox替換成listbox,設(shè)置一些選項供用戶選擇。為此,我們需要在模版列里指定一個EditItemIndex控件,當(dāng)用戶選擇一行編輯時,達(dá)到自定義HTML輸出效果的目的。前面提到過要自定義編輯界面,我們要用到模版列(TemplateColumn),而非綁定列(BoundColumn)。因此,首先我們需要將顯示category的綁定列轉(zhuǎn)換為模版列,如下面的代碼所顯(關(guān)于模版列的更多信息請參考Part 5):

<asp:datagrid id="dgPopularFAQs" runat="server" ... >
<Columns>
<asp:EditCommandColumn EditText="Edit" CancelText="Cancel"
UpdateText="OK" />

<asp:BoundColumn DataField="FAQID" ItemStyle-Width="10%"

ReadOnly="True"
ItemStyle-HorizontalAlign="Center"

HeaderText="FAQ ID" />

<asp:TemplateColumn HeaderText="Category">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "CategoryName") %>
</ItemTemplate>
</asp:TemplateColumn>

<asp:BoundColumn DataField="Description" HeaderText="FAQ Question"

/>
</Columns>
</asp:datagrid>

在此,我們僅僅從數(shù)據(jù)源將CategoryName列展示出來,還沒完;當(dāng)前,如果用戶點擊“Edit”按鈕的話,并不會呈現(xiàn)出某個category列,換句話說,他們只會看到category的text文本,而不是TextBox,DropDownList等。這是因為在編輯模式里編輯某行記錄的話,我們不使用綁定列那么就必須使用HTML。為此我們需要在TemplateColumn控件里使用EditItemTemplate(好比只顯示而不編輯數(shù)據(jù)時在ItemTemplate里用HTML呈現(xiàn)效果)

因此,在編輯模式里我們用DropDownList來顯示category。為此我們只需要添加DropDownList控件即可,像這樣:


<asp:TemplateColumn HeaderText="Category">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "CategoryName") %>
</ItemTemplate>

<EditItemTemplate>
<asp:DropDownList runat="server" id="lstCategories"
DataValueField="FAQCategoryID"
DataTextField="Name"
DataSource="???" />
</EditItemTemplate>
</asp:TemplateColumn>

既然我們希望DropDownList顯示現(xiàn)有的FAQ種類,我們需要將DropDownList綁定到一個數(shù)據(jù)源。當(dāng)對DropDownList進(jìn)行綁定時我們需要指定DropDownList顯示的文字和對應(yīng)的傳遞值。既然DropDownList顯示的每一項對應(yīng)表tblFAQCategory里的一行記錄,比較妥當(dāng)?shù)淖龇ㄊ荄ropDownList將種類的名稱(即Name列)顯示出來,而傳遞的值是AQCategoryID,因為在表tblFAQCategory里一個AQCategoryID對應(yīng)一個Name,而AQCategoryID是主鍵值(如果你對此完全被搞糊涂了,我建議你參考這篇文章:Creating Databound DropDown Lists in ASP.NET http://www.4guysfromrolla.com/webtech/071101-1.shtml )。這就是我在上文提到DataValueField和DataTextFields的原因。

當(dāng)然,我們應(yīng)該明白這樣道理:當(dāng)你指定DropDownList綁定哪些列時,實際上你已經(jīng)指定了數(shù)據(jù)源。從本質(zhì)上來說,我們需要用表tblFAQCategory的行記錄來構(gòu)建一個數(shù)據(jù)集(DataSet),在深入研究以前,我們先考察一下當(dāng)編輯DataGrid里的數(shù)據(jù)時,在后臺到底發(fā)生了什么呢?


考察DataGrid控件 Part 7 (中)

本文英文原版:
http://aspnet.4guysfromrolla.com/articles/080702-1.2.aspx


DataGrid的幕后機(jī)制

調(diào)用DataGrid的DataBind()方法時,它枚舉數(shù)據(jù)源的內(nèi)容。對數(shù)據(jù)源里的每一項(item),相應(yīng)的添加一個DataGridItem實例。每個DataGridItem都有一個ItemType屬性,要么被標(biāo)明為Item、或者AlternatingItem,又或者EditItem(當(dāng)然還有其它ItemType類型,不過對本例而言,我們只關(guān)注這3種)。添加的第一個(以及所有為奇數(shù))的DataGridItem被標(biāo)明為一個ItemType of Item(也就是Item、AlternatingItem或EditItem);而添加的第二個(以及所有為偶數(shù))的DataGridItem被標(biāo)明為AlternateItem。

一旦指定DataGridItem的ItemType屬性后,便可以運用相應(yīng)的用戶界面屬性。打個比方,如果指定ItemType屬性為Item,那么我們就可以使用Item對應(yīng)的ItemStyle屬性了。我們知道,DataGrid用Table類(Table class)來控制顯示界面(自然地,DataGrid呈現(xiàn)為一個HTML表格);此外DataGridItem源自于TableRow class類,那就意味著DataGridItem對象將呈現(xiàn)為一個HTML表格行(TABLE row).

記得DataGrid class類有一個EditItemIndex屬性,我們對DataGrid進(jìn)行編輯時就要用到這個屬性。比如,在DataGrid的OnEditCommand事件處理器里,我們要做的是將DataGrid的EditItemIndex設(shè)置為點擊了"Edit"按鈕的那一行的index值。 當(dāng)枚舉數(shù)據(jù)源時,如果當(dāng)前行與EditItemIndex相匹配,那么就將該DataGridItem行標(biāo)記為EditItem,進(jìn)行編輯。編輯時,如果某列為綁定列(BoundColumn),該列就呈現(xiàn)為默認(rèn)的TextBox,該TextBox的Text屬性的值就是用戶編輯輸入的值;如果某列為模版列(TempalteColumn),那么就呈現(xiàn)為它的EditItemTemplate(如果設(shè)置為available的話)。

綜上,當(dāng)調(diào)用DataGrid的DataBind()方法時,將對數(shù)據(jù)源進(jìn)行枚舉,數(shù)據(jù)將一行一行的添加到DataGrid(DataGrid從本質(zhì)來說就是一個HTML表格)。有一點很重要,對添加到DataGrid的每一行("row")來說,可以對其使用任何的數(shù)據(jù)綁定語法,就本章而言,我們就在模版列的ItemTemplate里使用了數(shù)據(jù)綁定語法(the <%# ... %>)。此外,行里的任何控件也有自己的DataBind()方法。


言歸正傳,對放置在EditItemTemplate標(biāo)簽里的DropDownList控件來說,當(dāng)調(diào)用DataGrid的DataBind()方法時,“處于編輯狀態(tài)的”DropDownList的DataBind()也會被調(diào)用。基于前面的知識,可以推斷出我們應(yīng)該將DropDownList的數(shù)據(jù)源設(shè)置為某個數(shù)據(jù)集(DataSet)并自動調(diào)用其DataBind()方法。問題是怎樣設(shè)置DropDownList的數(shù)據(jù)源(DataSource)屬性呢?答案是使用數(shù)據(jù)綁定語法!

指定DropDownList的DataSource屬性

我們使用我們熟悉的數(shù)據(jù)綁定語句來指定DropDownList的DataSource屬性,具體來說,我們用表tblFAQCategory來填充一個數(shù)據(jù)集,再用一個函數(shù)將該數(shù)據(jù)集返回,像下面這樣:

<asp:TemplateColumn HeaderText="Category">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "CategoryName") %>
</ItemTemplate>

<EditItemTemplate>
<asp:DropDownList runat="server" id="lstCategories"
DataValueField="FAQCategoryID"
DataTextField="Name"
DataSource="<%# GetCategories() %>" />
</EditItemTemplate>
</asp:TemplateColumn>

函數(shù)GetCategories()僅僅返回一個由表tblFAQCategory的行進(jìn)行填充的數(shù)據(jù)集。這個函數(shù)很簡單,像下面這樣:

<% @Import Namespace="System.Data" %>
<% @Import Namespace="System.Data.SqlClient" %>
<script language="vb" runat="server">
'Create a connection
Dim myConnection as New SqlConnection(connString)
Dim ddlDataSet as DataSet = New DataSet()

Function GetCategories() as DataSet
'Populate the ddlDataSet
Const strSQLDDL as String = _
"SELECT FAQCategoryID, Name FROM tblFAQCategory ORDER BY Name"

Dim myDataAdapter as SqlDataAdapter = New _
SqlDataAdapter(strSQLDDL, myConnection)

myDataAdapter.Fill(ddlDataSet, "Categories")

Return ddlDataSet
End Function

...
演示頁面為: http://aspnet.4guysfromrolla.com/demos/dgExample15.aspx

注意,數(shù)據(jù)庫連接(connection)和數(shù)據(jù)集ddlDataSet都是在頁面上定義的,這意味著ASP.NET Web 頁面上的任何一個函數(shù)都可以訪問這2個對象。對數(shù)據(jù)庫連接對象進(jìn)行完整(globally)定義的原因是我們要用到2個獲取數(shù)據(jù)庫信心的函數(shù)—GetCategories() 和 BindData()。相比起來,與其為這2個函數(shù)分別創(chuàng)建creating, opening和closing的分段連接對象,我們還不如直接使用完整的數(shù)據(jù)庫連接對象。請注意,該連接對象在達(dá)到目的時(也就是當(dāng)頁面完全顯示出來后)自動關(guān)閉。

GetCategories()函數(shù)簡單易懂,只是用表tblFAQCategory的查詢結(jié)果來填充數(shù)據(jù)集ddlDataSet,再將填充好了的數(shù)據(jù)集返回。在演示頁面里當(dāng)點擊"Edit"按鈕時,DropDownList控件確實被綁定了,再仔細(xì)看看,那發(fā)現(xiàn)了什么問題?

對了,當(dāng)點擊某行的"Edit"按鈕時,DropDownList顯示的是數(shù)據(jù)集里第一行的類類名,而非其本來的類名。比如,第一個FAQ的類名是"Strings",當(dāng)你點擊第一行的"Edit"按鈕后,顯示的卻是"Application Object"。還好,要修補(bǔ)這個小問題我們只需要使用一些數(shù)據(jù)綁定語法和代碼,我們在最后一部分再討論。

考察DataGrid控件 Part 7 (下)
本文英文原版
http://aspnet.4guysfromrolla.com/articles/080702-1.3.aspx

確保DropDownList恰當(dāng)?shù)腟elected Item

在編輯模式里,為確保DropDownList有恰當(dāng)?shù)腟elected Item,我們需要編程設(shè)置DropDownList的SelectedIndex屬性。為此,我們需要使用數(shù)據(jù)綁定語法,具體的說,我們要調(diào)用一個函數(shù),將所選擇的FAQ的FAQCategoryID值傳給它,代碼如下:

<asp:TemplateColumn HeaderText="Category">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "CategoryName") %>
</ItemTemplate>

<EditItemTemplate>
<asp:DropDownList runat="server" id="lstCategories"
DataValueField="FAQCategoryID"
DataTextField="Name"
DataSource="<%# GetCategories() %>"
SelectedIndex='<%# GetSelIndex(Container.DataItem("FAQCategoryID")) %>'
/>
</EditItemTemplate>
</asp:TemplateColumn>

函數(shù)GetSelIndex()接收的是編輯行的FAQCategoryID值(那就是為什么我們要在DataGrid里包含F(xiàn)AQCategoryID列,雖然并不在DataGrid里將該列顯示出來)。記得DropDownLis控件的SelectedIndex屬性是一個integer類型的值,且大小介于0和它包含的項的總數(shù)(number of items)之間。比方,我們想將選擇第五項,我們只需要將SelectedIndex屬性設(shè)置為4(因為第一項的index值為0)

所以,函數(shù)GetSelIndex()返回一個integer類型的值,它對應(yīng)DropDownList的所選項。我們知道數(shù)據(jù)集ddlDataSet用來填充(populate)控件DropDownList,同時數(shù)據(jù)集ddlDataSet每行的index與DropDownList的每項的index一一對應(yīng)。所以,函數(shù)GetSelIndex()遍歷數(shù)據(jù)集,將每行與傳入的FAQCategoryID值相比較。一旦匹配的話,函數(shù)就返回該行的index,然后對DropDownList的SelectedIndex屬性賦值。聽起來有點暈,下面的代碼也許能更好的便于你理解:

Function GetSelIndex(CatID as String) as Integer
Dim iLoop as Integer

'Loop through each row in the DataSet
Dim dt as DataTable = ddlDataSet.Tables("Categories")
For iLoop = 0 to dt.Rows.Count - 1
If Int32.Parse(CatID) = _
Int32.Parse(dt.Rows(iLoop)("FAQCategoryID")) then
Return iLoop
End If
Next iLoop
End Function

演示頁面為: http://aspnet.4guysfromrolla.com/demos/dgExample16.aspx


在OnUpdateCommand事件處理器里檢索DropDownList的值

當(dāng)用戶編輯某行記錄時,將會顯示"Update" 和 "Cancel"按鈕供選擇(在演示頁面里,我將"Update"替換為"OK"了)。當(dāng)用戶點擊"Update"按鈕時將觸發(fā)OnUpdateCommand事件。就像在Part 6探討過的一樣,為了用輸入的數(shù)據(jù)對數(shù)據(jù)庫進(jìn)行更新,我們需要為OnUpdateCommand事件編寫一個事件處理器。

為了獲取用戶從DropDownList選取的值,我們使用FindControl方法來得到DropDownList控件的實例;訪問SelectedItem.Value屬性,也就是用戶在DropDownList控件里所選的條目的FAQCategoryID值。OnUpdateCommand事件處理器的代碼如下:

Sub dgPopFAQs_Update(sender As Object, e As DataGridCommandEventArgs)
'Determine what category was selected
Dim strCategoryID as String, strCategoryName as String
strCategoryID = CType(e.Item.FindControl("lstCategories"), _
DropDownList).SelectedItem.Value
strCategoryName = CType(e.Item.FindControl("lstCategories"), _
DropDownList).SelectedItem.Text

... Make a SQL call to update the database ...

'Return the DataGrid to its pre-editing state
dgPopularFAQs.EditItemIndex = -1
BindData()
End Sub

演示頁面為: http://aspnet.4guysfromrolla.com/demos/dgExample17.aspx

使用EditItemTemplate定制其它編輯界面

在本文我們考察了使用EditItemTemplate來包含一個DropDownList控件。當(dāng)然,你也可以用它來為DataGrid里的其它列進(jìn)行編輯界面定制。比如,你可能覺得DataGrid默認(rèn)生成的TextBox 太小,你可以用EditItemTemplate來增大TextBox 的尺寸。另一個比較有實際意義的運用是,假如有一個Yes/No類型的列,你可以添加一個包含"Yes" / "No"值的DropDownList控件或干脆設(shè)置一個 單選按鈕,這比使用TextBox要好的多。

注意演示頁面,在編輯界面里我們使用的是75-column的TextBox.

結(jié)語:

本文對Part 6的內(nèi)容進(jìn)行了擴(kuò)展,允許對DataGrid的編輯界面進(jìn)行用戶定制。我們首先探討了如何來模版列里用EditItemTemplate對某個列進(jìn)行編輯界面定制。然后,考察了如何將表tblFAQCategory的內(nèi)容綁定到DropDownList,以及自動的選擇恰當(dāng)?shù)臈l目(item)。最后,我們學(xué)習(xí)了如何讀取用戶從DropDownList選取的值;這一步很重要,它關(guān)系到用用戶期望的值對數(shù)據(jù)庫進(jìn)行更新。

謹(jǐn)記,用EditItemTemplate對編輯界面進(jìn)行用戶定制的潛力是無窮的,只是看你的能力而已!

祝編程快樂!

考察DataGrid控件 Part 7


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 色视频在线看 | 成人免费动作大片黄在线 | 欧美日韩亚洲综合在线一区二区 | 色综合天天综合网亚洲影院 | 亚洲精品不卡久久久久久 | 在线观看亚洲视频 | 羞羞色院91 | 99免费观看视频 | 色综合成人| 成人国产mv免费视频 | 色综合天天综合网亚洲 | 国产成人精品久久亚洲高清不卡 | 五月伊人| 国产九九热视频 | 精品久久香蕉国产线看观看亚洲 | 爱爱小视频免费体验区在线观看 | 久久综合色视频 | 亚洲精品αv一区二区三区 亚洲精品爱爱久久 | 欧美一级在线免费观看 | 五月天婷婷在线免费观看 | 亚洲热在线 | 亚洲精品乱码久久久久蜜桃 | 亚洲国产精品一区二区不卡 | 日本99热| 在线中文字幕视频 | 久久老色鬼天天综合网观看 | 狠狠的操你| 日韩色视频一区二区三区亚洲 | 亚洲欧洲日产国码天堂 | 一本伊在人香蕉线观新在线 | 嫩草社区 | 欧美激情精品久久久久久大尺度 | 狠狠色丁香婷婷综合视频 | 老司机伊人 | 青娱乐久久 | 成人国产第一区在线观看 | 91亚洲国产在人线播放午夜 | 成人欧美一区二区三区黑人 | 久久精品免看国产 | 九九99热久久精品在线9 | 日批日韩在线观看 |