国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

ASP.NET中Datagrid常見錯誤

2024-07-10 12:56:27
字體:
來源:轉載
供稿:網友
摘要:學習如何避免在使用 asp.net datagrid 控件進行開發時可能發生的一些常見錯誤。
  datagrid 控件是 microsoft? asp.net 中功能最強、用途最廣的 web 控件之一,這一點已經得到了 asp.net 權威人士的認同。雖然 datagrid 控件易于使用,但同樣易于給使用者帶來麻煩。以下是許多人所犯的一些錯誤,這些人包括從初學者到富有經驗的 .net 專家。您可以看到許多苦悶的使用者在 asp.net 新聞組和論壇就這些錯誤提出問題。遵循本文概述的相當簡單的步驟,可以幫助您避免這些錯誤,并節約大量的開發時間。

  可以使用 datagrid 創建列表數據而沒有使用

  我知道您不會再使用如下所示的代碼,但 asp.net 領域中許多守舊的用戶仍在繼續使用它們:

response.write("<table>")
while mydatareader.read()
response.write("<tr>")
response.write("<td>")
response.write(mydatareader(0))
response.write("</td>")
response.write("</tr>")
loop
response.write("</table>")

  可以對以上代碼進行簡化,使其僅為:

<asp:datagrid runat="server" datasource="mydatareader"/>

  并調用 .databind() 方法。即使需要對html輸出進行特殊的控制,您也可以在用戶界面上記錄集的內容重復出現的情況下,使用某個數據 web 控件。

  忘記在 page_load 事件中檢查 ispostback

  最常見的錯誤之一是忘記在數據綁定之前檢查頁面的 ispostback 條件。例如,datagrid 處于“edit”(編輯)模式時,忽略該項檢查將導致已編輯的值被數據源中的原始值覆蓋。然而,該規則至少有一個主要的例外,請參閱持續使用大型 viewstate。

  以下是包含 ispostback 檢查的一個典型 page_load 事件。bindgrid() 是一個例程,用于導入并設置 datagrid 的數據源,并調用 databind() 方法。

sub page_load
if not ispostback then
bindgrid()
end if
end sub

  需要更大的靈活性時,仍堅持使用自動生成的列

  如果 datagrid 所處的環境需要任何一種特殊格式,或是需要使用 datagrid 中的其他任何 web 控件,那么必須關閉 autogeneratecolumns。將 autogeneratecolumns 屬性的設置保持為“true”(默認設置)的做法,僅在最簡單的 datagrid 方案中有效。但對幾乎所有實際的應用程序,必須將該屬性設置為“false”,并在 datagrid 聲明的 <columns></columns> 段中明確地指定列。microsoft visual studio? .net 用戶可以使用屬性生成器以圖形化的方式創建這些列。

  注意:如果將 autogeneratecolumns 的設置保持為“true”,并且在 datagrid 的 <columns> 段中指定了列,那么最終將得到對列的重復設置。系統將首先顯示特別聲明的列,隨后是所有自動生成的列。

  嘗試僅使用控件 id 來引用 datagrid 項目中的控件

  許多人沒有認識到,對于 datagrid 的 templatecolumn 下的 itemtemplate 中的控件(例如帶有“mytextbox”id 的 textbox 控件),不能在后面的代碼或是在 aspx 頁面的 <script> 段中用如下所示的代碼來直接調用該控件:

dim myvalue as string = mytextbox.text

  該代碼將導致可怕的“名稱‘mytextbox’沒有聲明”錯誤。

  因為 datagrid 是由多個行(項目)組成的,所以數據源中的每一行實際都會有一個單獨的“mytextbox”實例。asp.net 在每個控件的 id 前面加上該控件層次結構中每個命名容器的 id,這樣 textbox 將具有唯一的 id,與頁面中所有其他控件的 id 都不相同。例如,如果 mytextbox 處于 datagrid1 中,那么生成的 id 將是 datagrid1:_ctl2:mytextbox?!癬ctl2”代表 mytextbox 所處的當前行。頁面中其他 mytextbox 實例的 id 可能是 datagrid1:_ctl3:mytextbox、datagrid1:_ctl4:mytextbox 等等。要檢索需要查找的“mytextbox”值,需要對適當的 datagriditem 調用 findcontrol 方法。該 datagriditem 用作 textbox 的父命名容器。

  html:

<asp:datagrid runat="server" id="datagrid1">
<columns>
<asp:templatecolumn>
<itemtemplate>
<asp:textbox runat="server" id="mytextbox"/>
</itemtemplate>
</asp:templatecolumn>
</columns>

  代碼:

sub datagrid1_updatecommand(sender as object, e as datagridcommandeventargs)
 dim myvalue as string = ctype(e.item.findcontrol("mytextbox"), textbox).text
 '對 myvalue 執行操作
end sub

  對 findcontrol 調用的結果調用 ctype,將會把返回值由 object 類型強制轉換成 textbox 類型,以訪問 .text 屬性。

  忘記在每個 datagrid 事件中執行 .databind() 調用,從而導致回發

  一個常見的問題是:“當我點擊 datagrid 某一行中的 edit(編輯)鏈接時,頁面回發,且不包含任何數據。這是什么錯誤?”問題在于數據僅在頁面第一次被調用時綁定到網格。在每個 datagrid 事件(edit、update、cancel、page 或 sort)中,請確保設置了 datagrid 的 datasource 屬性(除非已經在 <asp:datagrid> 聲明中通過聲明的方式進行了設置),并對 datagrid 調用了 databind() 方法。

  運行時不必要地在 datagrid 中動態創建 datagrid 控件或列

  在某些業務和技術方案中,在運行時創建 asp.net 控件是必要的,也是完全合適的。例如,有時需要在選擇其他頁面選項后,才能在運行時確定用戶界面。或是要創建一個復合服務器控件,其中的每個子控件都需要動態創建,因為無法以聲明的方式創建這些子控件。如果遇到這些情況,請注意,提交頁面時不要保留這些動態控件。必須在頁面生命周期的早期,在每次回發時重新創建動態控件(例如在 page_init 事件中)。警言:創建控件要早,創建控件要勤。有關如何動態創建控件的詳細信息,請參閱 microsoft knowledge base 文章 how to:dynamically create controls in asp.net with visual basic .net。

  然而,如果 datagrid 應用程序中不是一定需要動態創建控件,請避免使用該技術,以免遇到麻煩。盡管可能創建動態 datagrid,但它們會引發各種事件,這通常都會令人頭疼。換句話說,不要動態創建控件,以避免因為創建控件使 aspx 文件變得散亂。

  持續使用大型 viewstate

  datagrid 控件會在頁面中添加大量的 viewstate,這一點令人討厭,因為這會導致呈現給用戶的頁面的總體大小急劇增加。要使頁面大小不增加,最簡單的方法是無論對整個頁面,還是單獨對某些特定的控件,都禁用 viewstate。例如,如果頁面不產生回發,那么對整個頁面禁用 viewstate 是安全的。否則,請對兩次回發之間狀態信息不會發生更改的各個控件禁用 viewstate,或者對不需要隱藏字段來跟蹤自身狀態的那些控件禁用 viewstate。

  對 datagrid 控件或包含 datagrid 的頁面禁用 viewstate 時,如果 datagrid 會啟動回發事件,那么需要執行一些特殊的步驟。首先,必須在每次回發時在 page_load 中重新綁定 datagrid。這有違常規做法(以及上述第二個問題中的描述)。但如果禁用 viewstate,該步驟是必需的,這樣在執行 page_load 后可以正確地引發其他 datagrid 事件。如果要處理以下 datagrid 事件中的任何一部分(或全部),那么還需要在 viewstate 中手動存儲一些 datagrid 屬性。例如,在禁用了 viewstate 的 datagrid 中進行編輯時,只要是在 page_load 中第一次綁定 datagrid 之前重新存儲 edititemindex,且 datagrid 處于編輯模式,那么只需將 edititemindex 儲存到 viewstate 就夠了。

  表 1:datagrid 事件與 viewstate 的依賴關系
事件 是否依賴于 viewstate? 要存儲在 viewstate 中的字段
itemcreated 無
itemdatabound 無
sortcommand 是 sortexpression
editcommand 是 edititemindex
pageindexchanged 是 currentpageindex
selectedindexchanged 無


  清單 1:啟用編輯、排序和分頁,但禁用 viewstate 的 datagrid 的示例代碼。

sub page_load
 if not viewstate("edititemindex") is nothing then
  datagrid1.edititemindex = viewstate("edititemindex")
 end if
 if not viewstate("currentpageindex") is nothing then
  datagrid1.currentpageindex = viewstate("currentpageindex")
 end if
 bindgrid()
end sub

sub bindgrid()
 dim dv as dataview
 dv = getdatasource()
 dv.sort = viewstate("sortexpression")
 datagrid1.datasource = dv
 datagrid1.databind()
end sub

sub datagrid1_sortcommand(s as object, e as datagridsortcommandeventargs)
 viewstate("sortexpression") = e.sortexpression
 bindgrid()
end sub

sub datagrid1_editcommand(s as object, e as datagridcommandeventargs)
 datagrid1.edititemindex = e.item.itemindex
 viewstate("edititemindex") = e.item.itemindex
 bindgrid()
end sub

sub datagrid1_pageindexchanged(s as object, e as datagridpagechangedeventargs)
 datagrid1.currentpageindex = e.newpageindex
 viewstate("currentpageindex") = e.newpageindex
 bindgrid()
end sub

  使用 itemdatabound 或 itemcreated 事件時,忘記檢查適當的 listitemtype

  datagrid 控件對每個數據行引發兩個事件。首次將每行添加到 datagrid 時將引發 itemcreated 事件,將數據綁定到每行時將引發 itemdatabound 事件。添加單元格到 datagrid 的表格輸出時,這些事件可以用于控制每個單元格的外觀或內容。例如,可以基于數值的范圍修改單元格的背景顏色。但關鍵是要記住,這些事件的引發針對的是所有 datagrid 項目類型,包括頁眉、頁腳和分頁程序項目。如果執行 itemdatabound 事件期間,沒有在引用項目的數據之前仔細檢查項目類型,第一個項目(通常是標題行)就將發生錯誤。如果 datagrid 啟用了分頁,且將其設置為在頂端顯示,那么第一個項目就會成為分頁程序項目。以下示例代碼顯示如何在引用項目數據之前進行正確的 listitemtype 檢查。不要忘了 alternatingitem!

sub datagrid1_itemdatabound(source as object,e as datagriditemeventargs)
if (e.item.itemtype = listitemtype.item or e.item.itemtype = listitemtype.alternatingitem)   then
  if e.item.dataitem("forumdate") < datetime.today then
    e.item.cells(1).backcolor =system.drawing.color.fromname("#ffccff")
  end if
 end if
end sub


  需要對生成的 html 有更多的控制時,過多地使用了 datagrid(repeater 也許是更好的選擇)

  如果懶散的程序員喜歡 datagrid 控件(因為 datagrid 控件為他們完成了很多工作),那么有著極強控制欲的程序員必定喜歡 repeater 控件。如果需要或希望完全控制創建的所有 html,請使用 repeater 控件,它能幫助您完成該任務。repeater 控件在性能上也略占優勢,因為它不像 datagrid 控件的所有內置功能那樣占用系統資源。也可以考慮使用折衷的 datalist 控件,它具備編輯和排序功能,同時還具有在一行內重復顯示記錄的功能。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 临漳县| 康保县| 昌乐县| 夏邑县| 鹿邑县| 云龙县| 金湖县| 肥西县| 荣成市| 买车| 龙海市| 伊川县| 永嘉县| 固镇县| 伊通| 天柱县| 洛宁县| 凯里市| 杂多县| 苏尼特左旗| 临武县| 康定县| 鹤庆县| 襄汾县| 三台县| 三亚市| 营山县| 莒南县| 梅河口市| 外汇| 永福县| 大洼县| 榆中县| 遂溪县| 温州市| 麻城市| 昌邑市| 太仓市| 浮梁县| 抚顺县| 乌拉特前旗|