2009年4月25日 星期六

讓 DropDownList DataBind 不再發生錯誤

DropDownList 在執行 DataBind 動作時,若 Items 集合中不存在繫結的欄位值時會發生 Exception。不過 DropDownList 這種設計方式常會造成困擾,很多時候繫結的欄位值無法預期,而且 DropDownList 控制項在這種狀況釋出的錯誤在頁面程式碼中無法處理。

為了解決這種情形,比較快的方式就是直接改掉 DropDownList,在控制項中處理這種無法繫結的情形才是最終的解決方案。那我們該從何處下手呢?想想通常 DropDownList 控制項做資料繫結的是什麼屬性呢?沒錯,就是 SelectedValue 屬性,那我們就從覆寫 SelectedValue 屬性下手,改寫 SelectedValue 屬性的 Set 動作;當寫入 SelectedValue 屬性時的新值不存在 Items 集合中時,就直接設定其 SelectedIndex = -1。這樣就可以很簡單決解掉 DropDownList 繫結錯誤的問題了。

Public Class TBDropDownList
Inherits DropDownList

''' <summary>
''' 覆寫 SelectedValue 屬性。
''' </summary>
Public Overrides Property SelectedValue() As String
Get
Return MyBase.SelectedValue
End Get
Set(ByVal value As String)
Dim oItem As ListItem = Me.Items.FindByValue(value)
If (oItem Is Nothing) Then
Me.SelectedIndex = -1 '當 Items 不存在時
Else
MyBase.SelectedValue = value
End If
End Set
End Property

End Class

=========分隔線=======

我自己是用這種方法,見紅字部份

ddl_City.DataSource = ds.Tables["CITY"];
ddl_City.DataValueField = "DATA_INDEX";
ddl_City.DataTextField = "DATA_VALUE";
//以下兩行避免bind不到資料
ddl_City.AppendDataBoundItems = true;
ddl_City.Items.Add("");
ddl_City.DataBind();

========又一條分格線======

找到的另一種方法

UserRoleID.SelectedIndex = UserRoleID.Items.IndexOf(UserRoleID.Items.FindByValue(dr["UserRoleID"].ToString()));

就是如果通過FindByValue沒有找到指定項則為null,而Items.IndexOf(null)會返回-1.

ListItem item = DropDownList1.Items.FindByValue("qqcrazyer");
if(item != null)
{
item.Selected = true;
}

說明: 執行當前 Web 請求期間,出現未處理的異常。請檢查堆棧跟蹤信息,以瞭解有關該錯誤以及代碼中導致錯誤的出處的詳細信息。

異常詳細信息: System.ArgumentOutOfRangeException: 「UserRoleID」有一個無效 SelectedValue,因為它不在項目列表中

沒有留言:

張貼留言