摘要
在「让 CheckBoxField 系结非布尔值(0 或 1)字段」一文中有介绍了如何修改 CheckFieldBox 去系结 0 或 1 的非布尔值,其作法是将非布尔直接使用 CBool 函式将字段值强制转型为布尔值。 不过有时系结的字段值并无法直接使用 CBool 转型为布尔值,例如 "T/F"、"是/否" 之类的资料,若希望使用 CheckBoxField 来显示就比较麻烦,一般的作法都是转为 TemplateField,自行撰写数据系结的函式,而且只能支持单向系结。在本文中我们将直接改写 CheckBoxField 类别,让 CheckBoxField 可以直接双向系结 "T/F" 或 "是/否" 之类的资料。
在「让 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 String, ByRef TrueValue As String, ByRef 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 Object) As 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 Boolean) As 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 Object, ByVal 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 > 0) Then
139 oControl = Cell.Controls.Item(0)
140 Dim oCheckBox As CheckBox = TryCast(oControl, CheckBox)
141 If ((Not oCheckBox Is Nothing) AndAlso (IncludeReadOnly OrElse oCheckBox.Enabled)) Then
142 If Me
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 String, ByRef TrueValue As String, ByRef 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 Object) As 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 Boolean) As 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 Object, ByVal 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 > 0) Then
139 oControl = Cell.Controls.Item(0)
140 Dim oCheckBox As CheckBox = TryCast(oControl, CheckBox)
141 If ((Not oCheckBox Is Nothing) AndAlso (IncludeReadOnly OrElse oCheckBox.Enabled)) Then
142 If Me
【上篇】WPF 4 开发Windows 7 任务栏(Overlay Icon、Thumbnail Toolbar、Progress Bar)
【下篇】Silverlight C# 游戏开发:资源的处理,图像算法(二)
【下篇】Silverlight C# 游戏开发:资源的处理,图像算法(二)