首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为不同类型创建自定义TypeConverter

为不同类型创建自定义TypeConverter
EN

Stack Overflow用户
提问于 2016-03-05 10:15:31
回答 1查看 476关注 0票数 0

嗨,我一直在思考如何实现以下目标:

我需要创建一个组件'ControlValidator‘,它扩展了一个名为Validator的属性,该属性的类型是ValidatorBase,该属性应该以ComboBox的形式在属性网格中显示,其中的值为{None, Required Field, Regular Expression}

  • 无=无验证
  • ValidatorBase扩展的必需字段=类
  • 正则表达式=从ValidatorBase扩展的类

这是带有代码的属性网格,它显示了我想要的属性,但我不能将Validation1设置为'none‘,如果我试图保存表单,它会说我分配给该属性的按钮正在生成一个空值:

这是我的密码,我真搞不懂。

谢谢!!

ControlValidator

代码语言:javascript
复制
<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 Class

ValidatorsBase

代码语言:javascript
复制
<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

必修课:

代码语言:javascript
复制
<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 Class

TypeConverter:

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2016-03-05 16:16:27

在你的方法中几乎没有什么缺陷。ValidatorsBase显然也是ErrorText版本,RegularExpression类型未显示。

  • 您正在扩展的属性是ValidatorsBase类型,但这将不允许您为更特定的类型设置RequiredRegEx文本属性。这些属性存在于其他类型上。
  • 如果属性为None为空,VS将不喜欢它;您也不会喜欢它,因为您必须执行大量的If thisCrtl.Validator1 IsNot Nothing Then...操作。
  • 我不知道这些对象是如何使用的,但是您根本没有创建任何对象,所以任何设计人员的任务都丢失了。

如果您将其抽象一点,那么可能有3条信息:Validation (None,ErrorMsg,Required,RegEx),一些文本,用作msg或RegEx,具体取决于规则,--一个布尔型

因此,对这些类使用一个简单的类,使用基本的ExpandableObjectConverter可以很好地满足您的需要:

代码语言:javascript
复制
' 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

然后,扩展者:

代码语言:javascript
复制
<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限制在一个控件上,比如最初的TextBoxNumericUpDn,那么当您更改名称或属性类型的想法时,不会有数百行设计人员代码无效。)

您的Get/Set对需要创建它们:

代码语言:javascript
复制
<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。设计师代码:

代码语言:javascript
复制
Validator2.Required = False
Validator2.Rule = ControlValidator.ValidationRule.None
Validator2.ValidationText = Nothing
Me.ControlValidator1.SetValidator(Me.nud2, Validator2)

实际上,我的Validator只不过是你所需要的信息的持有者。不过,这提供了多种使用它的方法:

  • 该类可以根据规则有条件地实现验证逻辑。
  • 类可以在内部创建“真正的”助手验证器。
  • 您的代码可以获取数据并从其中创建“真实”验证器对象。

您可能会发现一个全合一的Validator更有用:例如,ErrorText可能对RegExRequired规则都很有用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35812840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档