现在的位置: 首页 > 综合 > 正文

扩展 CheckBoxField 类别 – 支持非布尔值的双向系结

2012年05月19日 ⁄ 综合 ⁄ 共 6486字 ⁄ 字号 评论关闭
摘要
在「让 CheckBoxField 系结非布尔值(0 或 1)字段」一文中有介绍了如何修改 CheckFieldBox 去系结 0 或 1 的非布尔值,其作法是将非布尔直接使用 CBool 函式将字段值强制转型为布尔值。 不过有时系结的字段值并无法直接使用 CBool 转型为布尔值,例如 "T/F"、"是/否" 之类的资料,若希望使用 CheckBoxField 来显示就比较麻烦,一般的作法都是转为 TemplateField,自行撰写数据系结的函式,而且只能支持单向系结。在本文中我们将直接改写 CheckBoxField 类别,让 CheckBoxField 可以直接双向系结 "T/F" 或 "是/否" 之类的资料。

扩展 CheckBoxField 类别
我们继承 CheckBoxField 命名为 TBCheckBoxField,新增 DefineValue 属性,用来做布尔值转换定义(格式为 "True/False");若设定 DefineValue="是/否",即字段值为 "是" 对应到 True,而 "否" 对应到 False。
当读取字段值要系结至控件时会引发 OnDataBindField 方法;故覆写 OnDataBindField 方法,判断若有设定  DefineValue 属性,则利用 ValueToBoolean 方法将字段值依 DefineValue 的定义转换为布尔值。例如将 "男/女" 转为 "True/False",再与控件做系结。
当要写入数据时会由控件撷取出目前的字段值,此时会引发 ExtractValuesFromCell 方法;故覆写 ExtractValuesFromCell 方法,此时会撷取 CheckBoxField 内含的 CheckBox 控件的 Checked 属性值(布尔值),若有设定 DefineValue 属性时,会利用 BooleanToValue 方法将布尔值依 DefineValue 的定义转换为字段值。

  1Imports System.Collections.Specialized
  2Imports System.ComponentModel
  3Imports System.Web
  4Imports System.Web.UI
  5Imports System.Web.UI.WebControls
  6
  7Namespace WebControls
  8    < _
  9    Description("复选框字段") _
 10    > _
 11    Public Class TBCheckBoxField
 12        Inherits CheckBoxField
 13
 14        Private FDefineValue As String = String.Empty
 15
 16        ''' <summary>
 17        ''' 布尔值转换定义,格式为 "True/False"。
 18        ''' </summary>
 19        ''' <returns>
 20        ''' 当设定为 "T/F" 时,表示 T 为 True,F 为 False。
 21        ''' 当设定为 "T/*" 时,表示 T 为 True,其它为 False。
 22        ''' </returns> 

 23        Public Property DefineValue() As String
 24            Get
 25                Return FDefineValue
 26            End Get
 27            Set(ByVal value As String)
 28                FDefineValue = value
 29            End Set
 30        End Property

 31
 32        ''' <summary>
 33        ''' 解析布尔值转换定义。
 34        ''' </summary>
 35        ''' <param name="DefineValue">布尔值转换定义。</param>
 36        ''' <param name="TrueValue">True 的对应值。</param>
 37        ''' <param name="FalseValue">False 的对应值。</param>

 38        Private Sub ParserDefineValue(ByVal DefineValue As StringByRef TrueValue As StringByRef FalseValue As String)
 39            Dim oParts() As String
 40
 41            oParts = Split(Me.DefineValue, "/")
 42            If oParts.Length <> 2 Then
 43                Throw New HttpException("DefineValue 格式错误")
 44            End If
 45            TrueValue = oParts(0)
 46            FalseValue = oParts(1)
 47        End Sub

 48
 49        ''' <summary>
 50        ''' 字段值依 DefineValue 的定义转换为布尔值。
 51        ''' </summary>
 52        ''' <param name="Value">字段值。</param>

 53        Private Function ValueToBoolean(ByVal Value As ObjectAs Boolean
 54            Dim sFieldValue As String
 55            Dim sTrueValue As String
 56            Dim sFalseValue As String
 57
 58            sFieldValue = CStr(Value)
 59            sTrueValue = String.Empty
 60            sFalseValue = String.Empty
 61            ParserDefineValue(Me.DefineValue, sTrueValue, sFalseValue)
 62
 63            If sFieldValue = sTrueValue Then
 64                Return True
 65            Else
 66                Return False
 67            End If
 68        End Function

 69
 70        ''' <summary>
 71        ''' 布尔值依 DefineValue 的定义转换为字段值。
 72        ''' </summary>
 73        ''' <param name="Value">布尔值。</param>

 74        Private Function BooleanToValue(ByVal Value As BooleanAs Object
 75            Dim sTrueValue As String
 76            Dim sFalseValue As String
 77
 78            sTrueValue = String.Empty
 79            sFalseValue = String.Empty
 80            ParserDefineValue(Me.DefineValue, sTrueValue, sFalseValue)
 81
 82            If Value Then
 83                Return sTrueValue
 84            Else
 85                Return sFalseValue
 86            End If
 87        End Function

 88
 89
 90        ''' <summary>
 91        ''' 将字段值系结至 TBCheckBoxField 对象中的复选框。 
 92        ''' </summary>
 93        ''' <param name="sender">作用的控件。</param>
 94        ''' <param name="e">事件自变量。</param>

 95        Protected Overrides Sub OnDataBindField(ByVal sender As ObjectByVal e As EventArgs)
 96            Dim oControl As Control = DirectCast(sender, Control)
 97            Dim oNamingContainer As Control = oControl.NamingContainer
 98            Dim oFieldValue As Object = Me.GetValue(oNamingContainer)
 99
100            If Not TypeOf oControl Is CheckBox Then
101                Throw New HttpException("系结的控件非复选框")
102            End If
103
104            If IsDBNull(oFieldValue) Then
105                DirectCast(oControl, CheckBox).Checked = False
106            ElseIf TypeOf oFieldValue Is Boolean Then
107                DirectCast(oControl, CheckBox).Checked = CBool(oFieldValue)
108            Else
109                If Not Me.DesignMode Then
110                    Try
111                        If Me.DefineValue <> String.Empty Then
112                            DirectCast(oControl, CheckBox).Checked = ValueToBoolean(oFieldValue)
113                        Else
114                            DirectCast(oControl, CheckBox).Checked = CBool(oFieldValue)
115                        End If
116                    Catch exception As FormatException
117                        Throw New HttpException("无法将值转为布尔值", exception)
118                    End Try
119                End If
120            End If
121
122            DirectCast(oControl, CheckBox).Text = Me.Text
123        End Sub

124
125        ''' <summary>
126        ''' 使用指定 DataControlFieldCell 对象的值填入指定的 System.Collections.IDictionary 物件。 
127        ''' </summary>
128        ''' <param name="dictionary">用于储存指定储存格的值。</param>
129        ''' <param name="cell">包含要撷取值的储存格。</param>
130        ''' <param name="rowState">数据列的状态。</param>
131        ''' <param name="includeReadOnly">true 表示包含只读字段的值,否则为 false。</param>

132        Public Overrides Sub ExtractValuesFromCell(ByVal Dictionary As IOrderedDictionary, ByVal Cell As DataControlFieldCell, _
133            ByVal RowState As DataControlRowState, ByVal IncludeReadOnly As Boolean)
134            Dim oControl As Control = Nothing
135            Dim sDataField As String = Me.DataField
136            Dim oFieldValue As Object = Nothing
137
138            If (Cell.Controls.Count > 0Then
139                oControl = Cell.Controls.Item(0)
140                Dim oCheckBox As CheckBox = TryCast(oControl, CheckBox)
141                If ((Not oCheckBox Is NothingAndAlso (IncludeReadOnly OrElse oCheckBox.Enabled)) Then
142                    If Me

抱歉!评论已关闭.