嗨,我一直在思考如何实现以下目标:
我需要创建一个组件'ControlValidator‘,它扩展了一个名为Validator的属性,该属性的类型是ValidatorBase,该属性应该以ComboBox的形式在属性网格中显示,其中的值为{None, Required Field, Regular Expression}:
ValidatorBase扩展的必需字段=类ValidatorBase扩展的类这是带有代码的属性网格,它显示了我想要的属性,但我不能将Validation1设置为'none‘,如果我试图保存表单,它会说我分配给该属性的按钮正在生成一个空值:

这是我的密码,我真搞不懂。
谢谢!!
ControlValidator
<ProvideProperty("Validation1", GetType(Control))>
Public Class ControlValidator
Inherits Component
Implements IExtenderProvider
Private helpTexts As Hashtable
Public Sub New()
helpTexts = New Hashtable
End Sub
Public Function CanExtend(extendee As Object) As Boolean Implements IExtenderProvider.CanExtend
If TypeOf extendee Is Control AndAlso Not TypeOf extendee Is ControlValidator Then
Return True
Else
Return False
End If
End Function
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
<DefaultValue(GetType(ValidatorsBase), "None")>
Public Function GetValidation1(ByVal ctrl As Control) As ValidatorsBase
Dim myText As ValidatorsBase = helpTexts(ctrl)
If myText Is Nothing Then
Return Nothing
End If
Return myText
End Function
Public Sub SetValidation1(ByVal ctrl As Control, ByVal value As ValidatorsBase)
If value Is Nothing Then
helpTexts.Remove(ctrl)
Else
helpTexts(ctrl) = value
End If
End Sub
End ClassValidatorsBase
<TypeConverter(GetType(ValidatorsConverter))>
Public Class ValidatorsBase
Private _errorText As String
Public Property ErrorText() As String
Get
Return _errorText
End Get
Set(ByVal value As String)
_errorText = value
End Set
End Property
Public Overrides Function ToString() As String
Return "Validator"
End Function
End Class必修课:
<TypeConverter(GetType(ValidatorsConverter))>
Public Class RequiredField
Inherits ValidatorsBase
Private _required As Boolean
Public Property required() As Boolean
Get
Return _required
End Get
Set(ByVal value As Boolean)
_required = value
End Set
End Property
Public Overrides Function ToString() As String
Return "Required Field"
End Function
End ClassTypeConverter:
Public Class ValidatorsConverter
Inherits TypeConverter
Public Overrides Function CanConvertTo(context As ITypeDescriptorContext, destinationType As Type) As Boolean
Return destinationType = GetType(InstanceDescriptor) OrElse MyBase.CanConvertTo(context, destinationType)
End Function
Public Overrides Function CanConvertFrom(context As ITypeDescriptorContext, sourceType As Type) As Boolean
Return sourceType = GetType(String) OrElse MyBase.CanConvertFrom(context, sourceType)
End Function
Public Overrides Function ConvertFrom(context As ITypeDescriptorContext, culture As CultureInfo, value As Object) As Object
Dim result As Object = Nothing
If value Is Nothing OrElse value.ToString = "(none)" Then
result = "(none)"
ElseIf value.ToString = "Required Field" Then
result = New RequiredField
End If
Return result
End Function
Public Overrides Function GetPropertiesSupported(context As ITypeDescriptorContext) As Boolean
Return True
End Function
Public Overrides Function GetProperties(context As ITypeDescriptorContext, value As Object, attributes() As Attribute) As PropertyDescriptorCollection
Return TypeDescriptor.GetProperties(value, attributes)
End Function
Public Overrides Function GetStandardValuesSupported(context As ITypeDescriptorContext) As Boolean
Return True
End Function
Public Overrides Function GetStandardValues(context As ITypeDescriptorContext) As StandardValuesCollection
Dim values As New List(Of String)
values.Add("(none)")
values.Add("Required Field")
Return New StandardValuesCollection(values)
End Function
End Class发布于 2016-03-05 16:16:27
在你的方法中几乎没有什么缺陷。ValidatorsBase显然也是ErrorText版本,RegularExpression类型未显示。
ValidatorsBase类型,但这将不允许您为更特定的类型设置Required或RegEx文本属性。这些属性存在于其他类型上。None为空,VS将不喜欢它;您也不会喜欢它,因为您必须执行大量的If thisCrtl.Validator1 IsNot Nothing Then...操作。如果您将其抽象一点,那么可能有3条信息:Validation (None,ErrorMsg,Required,RegEx),一些文本,用作msg或RegEx,具体取决于规则,--一个布尔型。
因此,对这些类使用一个简单的类,使用基本的ExpandableObjectConverter可以很好地满足您的需要:
' simple, easy TypeConverter to expand the object to reveal the properties
<TypeConverter(GetType(ExpandableObjectConverter))>
Public Class Validator
Public Property Rule As ControlValidator.ValidationRule
Public Property ValidationText() As String
<Description("This field is Required By Law")>
Public Property Required As Boolean
Public Sub New()
End Sub
Public Sub New(r As ControlValidator.ValidationRule)
Rule = r
End Sub
Public Overrides Function ToString() As String
Return Rule.ToString()
End Function
End Class然后,扩展者:
<ProvideProperty("Validator", GetType(Control))>
Public Class ControlValidator
Inherits Component
Implements IExtenderProvider
Public Enum ValidationRule
None
RequiredField
RegularExpression
End Enum
Private helpTexts As Dictionary(Of Control, Validator)(提示:如果您将CanExtend限制在一个控件上,比如最初的TextBox或NumericUpDn,那么当您更改名称或属性类型的想法时,不会有数百行设计人员代码无效。)
您的Get/Set对需要创建它们:
<Category("Uber Validator"), DisplayName("Validator")>
<Description("Validation type to apply to this control")>
Public Function GetValidator(ByVal ctrl As Control) As Validator
If helpTexts.ContainsKey(ctrl) Then
Return helpTexts(ctrl)
Else
Return New Validator(ValidationRule.None)
End If
End Function
Public Sub SetValidator(ByVal ctrl As Control, ByVal value As Validator)
If helpTexts.ContainsKey(ctrl) Then
helpTexts(ctrl) = value
Else
helpTexts.Add(ctrl, value)
End If
End Sub如图所示,您可以更改的可怕的默认显示:

到目前为止,VS能够为我们序列化Validator。设计师代码:
Validator2.Required = False
Validator2.Rule = ControlValidator.ValidationRule.None
Validator2.ValidationText = Nothing
Me.ControlValidator1.SetValidator(Me.nud2, Validator2)实际上,我的Validator只不过是你所需要的信息的持有者。不过,这提供了多种使用它的方法:
您可能会发现一个全合一的Validator更有用:例如,ErrorText可能对RegEx和Required规则都很有用。
https://stackoverflow.com/questions/35812840
复制相似问题