在UserControl上放一个CheckBox,名称为chk.一个Label,名称为lbl,index为0.一个TextBox,名称为txt,index为0.
控件的功能是想实现一个CheckTextBox,有多个Label和多个TextBox.其中有一个属性为Rows.设计时正常。把Rows属性设为3
运行时,设置端点后,发现先运行UserControl_Initialize,接下来是UserControl_WriteProperties,
在UserControl_WriteProperties事件的End Sub代码上设置端点,监测m_Rows的值为3,按F8,代码跳到
UserControl_Resize事件,这时候监测m_Rows的值突然变为0了。导致程序出错。代码如下
Option Explicit
'自定义常量
Const TOP_MERGIN = 0
Const BOTTOM_MERGIN = 24
Const HEIGHT_GAP = 0
Const WIDTH_GAP = 24
'缺省值属性常量
Const m_def_Caption = "CheckTextBox"
Const m_def_DataFormat = "XXXX"
Const m_def_ControlCode = "00"
Const m_def_FlagCode = "0000"
Const m_def_ReadOnly = False
Const m_def_TextBoxWidth = 1000
Const m_def_LabelForeColor = vbBlack
Const m_def_TextBoxBackColor = vbWhite
Const m_def_TextBoxForeColor = vbBlack
Const m_def_BackColorStart = &HC0C0FF
Const m_def_BackColorEnd = &HC0C0FF
Const m_def_Rows = 1
Const m_def_MaxRow = 255
'属性变量
Dim m_Caption As String
Dim m_DataFormat As String
Dim m_ControlCode As String
Dim m_FlagCode As String
Dim m_ReadOnly As Boolean
Dim m_TextBoxWidth As Long
Dim m_LabelForeColor As OLE_COLOR
Dim m_LabelFont As Font
Dim m_TextBoxBackColor As OLE_COLOR
Dim m_TextBoxForeColor As OLE_COLOR
Dim m_Font As Font
Dim m_BackColorStart As OLE_COLOR
Dim m_BackColorEnd As OLE_COLOR
Dim m_Rows As Long
Dim m_MaxRow As Long
控件的功能是想实现一个CheckTextBox,有多个Label和多个TextBox.其中有一个属性为Rows.设计时正常。把Rows属性设为3
运行时,设置端点后,发现先运行UserControl_Initialize,接下来是UserControl_WriteProperties,
在UserControl_WriteProperties事件的End Sub代码上设置端点,监测m_Rows的值为3,按F8,代码跳到
UserControl_Resize事件,这时候监测m_Rows的值突然变为0了。导致程序出错。代码如下
Option Explicit
'自定义常量
Const TOP_MERGIN = 0
Const BOTTOM_MERGIN = 24
Const HEIGHT_GAP = 0
Const WIDTH_GAP = 24
'缺省值属性常量
Const m_def_Caption = "CheckTextBox"
Const m_def_DataFormat = "XXXX"
Const m_def_ControlCode = "00"
Const m_def_FlagCode = "0000"
Const m_def_ReadOnly = False
Const m_def_TextBoxWidth = 1000
Const m_def_LabelForeColor = vbBlack
Const m_def_TextBoxBackColor = vbWhite
Const m_def_TextBoxForeColor = vbBlack
Const m_def_BackColorStart = &HC0C0FF
Const m_def_BackColorEnd = &HC0C0FF
Const m_def_Rows = 1
Const m_def_MaxRow = 255
'属性变量
Dim m_Caption As String
Dim m_DataFormat As String
Dim m_ControlCode As String
Dim m_FlagCode As String
Dim m_ReadOnly As Boolean
Dim m_TextBoxWidth As Long
Dim m_LabelForeColor As OLE_COLOR
Dim m_LabelFont As Font
Dim m_TextBoxBackColor As OLE_COLOR
Dim m_TextBoxForeColor As OLE_COLOR
Dim m_Font As Font
Dim m_BackColorStart As OLE_COLOR
Dim m_BackColorEnd As OLE_COLOR
Dim m_Rows As Long
Dim m_MaxRow As Long
Private isProcessCurResizeEnd As Boolean
'是否选择
Public Property Get Value() As CheckBoxConstants
Value = chk.Value
End Property
Public Property Let Value(ByVal New_Value As CheckBoxConstants)
chk.Value() = New_Value
PropertyChanged "Value"
End Property
'标题组
Public Property Get Caption() As String
Caption = m_Caption
End Property
Public Property Let Caption(ByVal New_Caption As String)
m_Caption = New_Caption
PropertyChanged "Caption"
End Property
'格式组
Public Property Get DataFormat() As String
DataFormat = m_DataFormat
End Property
Public Property Let DataFormat(ByVal New_DataFormat As String)
m_DataFormat = New_DataFormat
PropertyChanged "DataFormat"
End Property
'控制码
Public Property Get ControlCode() As String
ControlCode = m_ControlCode
End Property
Public Property Let ControlCode(ByVal New_ControlCode As String)
m_ControlCode = New_ControlCode
PropertyChanged "ControlCode"
End Property
'标识码
Public Property Get FlagCode() As String
FlagCode = m_FlagCode
End Property
Public Property Let FlagCode(ByVal New_FlagCode As String)
m_FlagCode = New_FlagCode
PropertyChanged "FlagCode"
End Property
'是否只读
Public Property Get ReadOnly() As Boolean
ReadOnly = m_ReadOnly
End Property
Public Property Let ReadOnly(ByVal New_ReadOnly As Boolean)
m_ReadOnly = New_ReadOnly
PropertyChanged "ReadOnly"
End Property
'文本框部分宽度
Public Property Get TextBoxWidth() As Long
TextBoxWidth = m_TextBoxWidth
End Property
Public Property Let TextBoxWidth(ByVal New_TextBoxWidth As Long)
m_TextBoxWidth = New_TextBoxWidth
PropertyChanged "TextBoxWidth"
End Property
'标题部分前景色
Public Property Get LabelForeColor() As OLE_COLOR
LabelForeColor = m_LabelForeColor
End Property
Public Property Let LabelForeColor(ByVal New_LabelForeColor As OLE_COLOR)
m_LabelForeColor = New_LabelForeColor
PropertyChanged "LabelForeColor"
End Property
'文本框部分背景色
Public Property Get TextBoxBackColor() As OLE_COLOR
TextBoxBackColor = m_TextBoxBackColor
End Property
Public Property Let TextBoxBackColor(ByVal New_TextBoxBackColor As OLE_COLOR)
m_TextBoxBackColor = New_TextBoxBackColor
PropertyChanged "TextBoxBackColor"
End Property
'文本框部分前景色
Public Property Get TextBoxForeColor() As OLE_COLOR
TextBoxForeColor = m_TextBoxForeColor
End Property
Public Property Let TextBoxForeColor(ByVal New_TextBoxForeColor As OLE_COLOR)
m_TextBoxForeColor = New_TextBoxForeColor
PropertyChanged "TextBoxForeColor"
End Property
'字体(需要重新调整布局)
Public Property Get Font() As Font
Set Font = m_Font
End Property
Public Property Set Font(ByVal New_Font As Font)
Set m_Font = New_Font
PropertyChanged "Font"
End Property
'控件背景开始颜色
Public Property Get BackColorStart() As OLE_COLOR
BackColorStart = m_BackColorStart
End Property
Public Property Let BackColorStart(ByVal New_BackColorStart As OLE_COLOR)
m_BackColorStart = New_BackColorStart
PropertyChanged "BackColorStart"
End Property
'控件背景开始颜色
Public Property Get BackColorEnd() As OLE_COLOR
BackColorEnd = m_BackColorEnd
End Property
Public Property Let BackColorEnd(ByVal New_BackColorEnd As OLE_COLOR)
m_BackColorEnd = New_BackColorEnd
PropertyChanged "BackColorEnd"
End Property
'当前行数(需要重新调整布局)
Public Property Get Rows() As Long
Rows = m_Rows
End Property
Public Property Let Rows(ByVal New_Rows As Long)
'检查合法性
If (New_Rows > m_MaxRow) Or (New_Rows < 1) Then
Exit Property
End If
Call SetLayout(New_Rows)
m_Rows = New_Rows
PropertyChanged "Rows"
End Property
'最大行数
Public Property Get MaxRow() As Long
MaxRow = m_MaxRow
End Property
Public Property Let MaxRow(ByVal New_MaxRow As Long)
If New_MaxRow > m_def_MaxRow Then
Exit Property
End If
m_MaxRow = New_MaxRow
PropertyChanged "MaxRow"
End Property
'可以触发resize事件
isProcessCurResizeEnd = True
End Sub'控件初始化
Private Sub UserControl_InitProperties()
m_Caption = m_def_Caption
m_DataFormat = m_def_DataFormat
m_ControlCode = m_def_ControlCode
m_FlagCode = m_def_FlagCode
m_ReadOnly = m_def_ReadOnly
m_TextBoxWidth = m_def_TextBoxWidth
m_LabelForeColor = m_def_LabelForeColor
Set m_Font = Ambient.Font
m_TextBoxBackColor = m_def_TextBoxBackColor
m_TextBoxForeColor = m_def_TextBoxForeColor
m_BackColorStart = m_def_BackColorStart
m_BackColorEnd = m_def_BackColorEnd
m_Rows = m_def_Rows
m_MaxRow = m_def_MaxRow
End Sub
'从存储器加载属性值
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
chk.Value = PropBag.ReadProperty("Value", 0)
m_Caption = PropBag.ReadProperty("Caption", m_def_Caption)
m_DataFormat = PropBag.ReadProperty("DataFormat", m_def_DataFormat)
m_ControlCode = PropBag.ReadProperty("ControlCode", m_def_ControlCode)
m_FlagCode = PropBag.ReadProperty("FlagCode", m_def_FlagCode)
m_ReadOnly = PropBag.ReadProperty("ReadOnly", m_def_ReadOnly)
m_TextBoxWidth = PropBag.ReadProperty("TextBoxWidth", m_def_TextBoxWidth)
m_LabelForeColor = PropBag.ReadProperty("LabelForeColor", m_def_LabelForeColor)
Set m_Font = PropBag.ReadProperty("Font", Ambient.Font)
m_TextBoxBackColor = PropBag.ReadProperty("TextBoxBackColor", m_def_TextBoxBackColor)
m_TextBoxForeColor = PropBag.ReadProperty("TextBoxForeColor", m_def_TextBoxForeColor)
m_BackColorStart = PropBag.ReadProperty("BackColorStart", m_def_BackColorStart)
m_BackColorEnd = PropBag.ReadProperty("BackColorEnd", m_def_BackColorEnd)
m_Rows = PropBag.ReadProperty("Rows", m_def_Rows)
m_MaxRow = PropBag.ReadProperty("MaxRow", m_def_MaxRow)
End Sub
'保存属性值到存储器中
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
Call PropBag.WriteProperty("Value", chk.Value, 0)
Call PropBag.WriteProperty("Caption", m_Caption, m_def_Caption)
Call PropBag.WriteProperty("DataFormat", m_DataFormat, m_def_DataFormat)
Call PropBag.WriteProperty("ControlCode", m_ControlCode, m_def_ControlCode)
Call PropBag.WriteProperty("FlagCode", m_FlagCode, m_def_FlagCode)
Call PropBag.WriteProperty("ReadOnly", m_ReadOnly, m_def_ReadOnly)
Call PropBag.WriteProperty("TextBoxWidth", m_TextBoxWidth, m_def_TextBoxWidth)
Call PropBag.WriteProperty("LabelForeColor", m_LabelForeColor, m_def_LabelForeColor)
Call PropBag.WriteProperty("Font", m_Font, Ambient.Font)
Call PropBag.WriteProperty("TextBoxBackColor", m_TextBoxBackColor, m_def_TextBoxBackColor)
Call PropBag.WriteProperty("TextBoxForeColor", m_TextBoxForeColor, m_def_TextBoxForeColor)
Call PropBag.WriteProperty("BackColorStart", m_BackColorStart, m_def_BackColorStart)
Call PropBag.WriteProperty("BackColorEnd", m_BackColorEnd, m_def_BackColorEnd)
Call PropBag.WriteProperty("Rows", m_Rows, m_def_Rows)
Call PropBag.WriteProperty("MaxRow", m_MaxRow, m_def_MaxRow)
End Sub
'控件大小发生变化
Private Sub UserControl_Resize()
If Not isProcessCurResizeEnd Then Exit Sub
Call SetLayout(m_Rows)
End Sub
'加载控件数组,如果Rows变小了,则要卸载控件数组
Private Sub SetLayout(CurRows As Long)
Dim i As Long
'加载控件
If CurRows > txt.Count Then
For i = txt.Count To CurRows - 1
Load lbl(i): lbl(i).Visible = True
Load txt(i): txt(i).Visible = True
Next i
'卸载控件
ElseIf CurRows < txt.Count Then
For i = txt.Count - 1 To CurRows Step -1
Unload lbl(i)
Unload txt(i)
Next i
End If
'调整位置,由于SetPostion中代码会触发UserControl_Resize事件,因此设置标志
isProcessCurResizeEnd = False
Call SetPostion(CurRows)
isProcessCurResizeEnd = True
End Sub
''调整位置
Private Sub SetPostion(CurRows As Long)
Dim i As Long
Dim maxLblWidth As Long
Dim MinCtlWidth As Long
For i = 0 To CurRows - 1
If maxLblWidth < lbl(i).Width Then
maxLblWidth = lbl(i).Width
End If
Next i
MinCtlWidth = chk.Width + maxLblWidth + txt(0).Width + WIDTH_GAP * 3
'设置usercontrol高度,宽度最后根据标题长度再设置
UserControl.Height = txt(0).Height * txt.Count + (txt.Count - 1) * HEIGHT_GAP + TOP_MERGIN + BOTTOM_MERGIN
If UserControl.Width < MinCtlWidth Then UserControl.Width = MinCtlWidth
'设置文本框位置
For i = 0 To txt.Count - 1
txt(i).Left = UserControl.Width - WIDTH_GAP - txt(0).Width
txt(i).Top = TOP_MERGIN + (txt(0).Height + HEIGHT_GAP) * i
Next i
'设置label的位置
For i = 0 To lbl.Count - 1
lbl(i).Left = txt(i).Left - WIDTH_GAP - lbl(i).Width
lbl(i).Top = txt(i).Top + 45
Next i
End Sub