DropDownList 控件常常会因为项目清单中不存在系结的字段,而发生以下的错误讯息。因为系结数据的不完整或异常就会造成这样的异常错误,在设计上实在是相当困扰,而且最麻烦的是这个错误在页面的程序代码也无法使用 Try ... Catch 方式来略过错误。其实最简单的方式就去直接去修改 DropDownList 控件,让 DropDownList 控件系结数据时,就算字段值不存在清单项目中也不要释出错误,本文就要说明如何继承 DorpDownList 下来修改,来有效解决这个问题。
程序代码下载:ASP.NET Server Control - Day22.rar
Northwnd 数据库下载:NORTHWND.rar
一、覆写 SelectedValue 属性解决数据系结的问题
DropDownList 控件系结错误的原因,可以由上图的错误讯息可以大概得知是写入 SelectedValue 属性时发生的错误;所以我们继承 DorpDownList 下来命名为 TBDropDownList,并覆写 SelectedValue 属性来解决这个问题。解决方式是在写入 SelectedValue 属性时,先判断准备写入的值是否存在项目清单中,存在的话才写入 SelectedValue 属性,若不存在则直接设定 SelectedIndex 属性为 -1。
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 不存在時
Exit Property
Else
MyBase.SelectedValue = value
End If
End Set
End Property
End Class
我们以 Northwnd 数据库的 Products 数据表做为测试数据,事先定义 DropDownList 的 Items 内容,其中第一个加入 "未对应" 的项目,将 SelectedValue 属性系结至 CategoryID 字段。
<bee:TBDropDownList ID="DropDownList1" runat="server"
SelectedValue='<%# Bind("CategoryID") %>'>
<asp:ListItem Value="">未對應</asp:ListItem>
<asp:ListItem Value="2">Condiments</asp:ListItem>
<asp:ListItem Value="3">Confections</asp:ListItem>
</bee:TBDropDownList>
当资料的 CategoryID 字段值不存在于 DropDownList 的 Items 集合属性中时,就会显示第一个 "未对应" 的项目。
二、TBDropDownList 设定 DataSoruceID 产生的问题
上述的解决方法在笔者的「让 DropDownList DataBind 不再发生错误」一文中已经有提及,不过有读者发现另一个问题,就是当 DropDownList 设定 DataSourceID 时却会发生数据无法正常系结,以下就来解决这个问题。
我们设定 TBDropDownList 的 DataSoruceID 来取得项目清单的内容,将 DataSourceID 设定为另一个取得 Categories 数据表内容的 SqlDataSource 控件。
<bee:TBDropDownList ID="DropDownList1" runat="server"
SelectedValue='<%# Bind("CategoryID") %>' DataSourceID="SqlDataSource2"
DataTextField="CategoryName" DataValueField="CategoryID">
</bee:TBDropDownList>
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:Northwnd %>"
SelectCommand="SELECT CategoryID, CategoryName, Description, Picture FROM Categories"
ProviderName="<%$ ConnectionStrings:Northwnd.ProviderName %>" >
</asp:SqlDataSource>
当执行程序时,FormView 原本在浏览模式时的 CategoryID 字段值为 7 (CategoryName 应为 Product)。
当按下「编辑」时切换到 EditItemTemplate 时,改用 TBDropDownList 系结 CategoryID 字段值,可以这时欲无法系结正确的值。
三、解决 TBDropDownList 设定 DataSourceID 造成数据无法系结的问题
要解决上述 TBDropDownList 设定 DataSourceID 问题,需在设定 SelectedValue 属性时,若 Items.Count=0 先用一个 FCachedSelectedValue 变量将正确的值先暂存下来,然后覆写 PerformDataBinding 方法,当 DorpDownList 取得 DataSoruceID 所对应的项目清单内容后,因为这时 Items 的内容才会完整取回,再去设定一次 SelectedValue 属性就可以正确的系结数据。
Public Class TBDropDownList
Inherits DropDownList
Private FCachedSelectedValue As String
''' <summary>
''' 覆寫 SelectedValue 屬性。
''' </summary>
Public Overrides Property SelectedValue() As String
Get
Return MyBase.SelectedValue
End Get
Set(ByVal value As String)
If Me.Items.Count <> 0 Then
Dim oItem As ListItem = Me.Items.FindByValue(value)
If (oItem Is Nothing) Then
Me.SelectedIndex = -1 '當 Items 不存在時
Else
MyBase.SelectedValue = value
End If
Else
FCachedSelectedValue = value
End If
End Set
End Property
Protected Overrides Sub PerformDataBinding(ByVal data As System.Collections.IEnumerable)
MyBase.PerformDataBinding(data)
'DataSoruceID 資料繫結後再設定 SelectedValue 屬性值
If (Not FCachedSelectedValue Is Nothing) Then
Me.SelectedValue = FCachedSelectedValue
End If
End Sub
End Class
重新执行程序,切换到编辑模式时,TBDropDownList 就可以正确的系结字段值了。
备注:本文同步发布于「第一届iT邦帮忙铁人赛」,如果你觉得这篇文章对您有帮助,记得连上去推鉴此文增加人气 ^^
http://ithelp.ithome.com.tw/question/10012909
http://ithelp.ithome.com.tw/question/10012915