在ASP.Net 2.0 網站頁面的開發過程中,經常需要把DropDownList等列表類控件的SelectedValue值設置為一個從數據庫或其他地方讀取出來的值。
最簡單的辦法就是直接進行指定:
DropDownList1.SelectedValue = "中國";
但有的時候如果DropDownList1中沒有"中國"這一項的話,賦值就會出現異常:
異常詳細信息: System.ArgumentOutOfRangeException: “DropDownList1”有一個無效 SelectedValue,因為它不在項目列表中。
想要實現的目標:如果指定的值不在列表項中,則不設置選中項,而且不要拋出異常。
查看MSDN:
SelectedValue 屬性還可以用於選擇列表控件中的某一項,方法是用該項的值設置此屬性。如果列表控件中的任何項都不包含指定值,則會引發 System.ArgumentOutOfRangeException。
但奇怪的是這樣賦值在大部分情況下都不會出錯,只是偶爾會出錯,通過反射查了一下SelectedValue的實現,找到了原因。
public virtual string SelectedValue
{
get
{
int num1 = this.SelectedIndex;
if (num1 >= 0)
{
return this.Items[num1].Value;
}
return string.Empty;
}
set
{
if (this.Items.Count != 0)
{
if ((value == null) || (base.DesignMode && (value.Length == 0)))
{
this.ClearSelection();
return;
}
ListItem item1 = this.Items.FindByValue(value);
if ((((this.Page != null) && this.Page.IsPostBack) && this._stateLoaded) && (item1 == null))
{
throw new ArgumentOutOfRangeException("value", SR.GetString("ListControl_SelectionOutOfRange", new object[] { this.ID, "SelectedValue" }));
}
if (item1 != null)
{
this.ClearSelection();
item1.Selected = true;
}
}
this.cachedSelectedValue = value;
}
}
原來只有在頁面是IsPostBack的情況下,賦值才會出錯。
另外這樣寫也會出現異常:
DropDownList1.Items.FindByValue("中國").Selected = true;
最後找到了一種方法可以實現上面的要求:
DropDownList1.SelectedIndex = DropDownList1.Items.IndexOf(DropDownList1.Items.FindByValue("中國"));
就是如果通過FindByValue沒有找到指定項則為null,而Items.IndexOf(null)會返回-1