【问题标题】:Why is my property appearing readonly为什么我的属性显示为只读
【发布时间】:2013-09-16 14:58:58
【问题描述】:

为什么PropertyGrid 中的以下属性是只读的?

Public Property Location() As PointF
    Get
        Return New PointF(mLeft, mTop)
    End Get
    Set(ByVal value As PointF)
        mLeft = value.X
        mTop = value.Y
    End Set
End Property

虽然同一对象的以下属性看起来很好(读/写):

Public Property Size() As SizeF
    Get
        Return New SizeF(mWidth, mHeight)
    End Get
    Set(ByVal value As SizeF)
        mWidth = value.Width
        mHeight = value.Height
    End Set
End Property

事实上,PropertyGrid 显示了我的第一个属性的 ToString() 版本,即 Location 的值类似于 {X=103, Y=235}

【问题讨论】:

    标签: .net vb.net propertygrid


    【解决方案1】:

    因为 SizeF 定义了默认的TypeConverter

    [Serializable, StructLayout(LayoutKind.Sequential), ComVisible(true), TypeConverter(typeof(SizeFConverter))]
    public struct SizeF
    {
       ...
    }
    

    虽然 PointF 没有:

    [Serializable, StructLayout(LayoutKind.Sequential), ComVisible(true)]
    public struct PointF
    {
        ....
    }
    

    【讨论】:

    • 我自己无法找到。谢谢一百万。
    【解决方案2】:

    对于其他将头撞到墙上的人,这里是 PointFConverter 类:

    Imports System.ComponentModel
    
    Public Class PointFConverter
        Inherits ExpandableObjectConverter
    
        Public Overrides Function CanConvertFrom(context As ITypeDescriptorContext, sourceType As Type) As Boolean
            If sourceType = GetType(String) Then
                Return True
            Else
                Return MyBase.CanConvertFrom(context, sourceType)
            End If
        End Function
    
        Public Overrides Function ConvertFrom(context As ITypeDescriptorContext, culture As System.Globalization.CultureInfo, value As Object) As Object
            If TypeOf value Is String Then
                Try
                    Dim s As String = DirectCast(value, String)
                    Dim converterParts As String() = s.Split(","c)
                    Dim x As Single = 0.0F
                    Dim y As Single = 0.0F
                    If converterParts.Length > 1 Then
                        x = Single.Parse(converterParts(0).Trim())
                        y = Single.Parse(converterParts(1).Trim())
                    ElseIf converterParts.Length = 1 Then
                        x = Single.Parse(converterParts(0).Trim())
                    End If
                    Return New PointF(x, y)
                Catch
                    Throw New ArgumentException("Cannot convert [" + value.ToString() + "] to pointF")
                End Try
            End If
            Return MyBase.ConvertFrom(context, culture, value)
        End Function
    
        Public Overrides Function ConvertTo(context As ITypeDescriptorContext, culture As System.Globalization.CultureInfo, value As Object, destinationType As Type) As Object
            If destinationType = GetType(String) Then
                If value.[GetType]() = GetType(PointF) Then
                    Dim pt As PointF = DirectCast(value, PointF)
                    Return String.Format("{0}, {1}", pt.X, pt.Y)
                End If
            End If
    
            Return MyBase.ConvertTo(context, culture, value, destinationType)
        End Function
    End Class
    

    只需像这样将它应用到您的财产上:

    <TypeConverter(GetType(PointFConverter))> _
    Public Property Location() As PointF
        Get
            Return New PointF(mLeft, mTop)
        End Get
        Set(ByVal value As PointF)
            mLeft = value.X
            mTop = value.Y
        End Set
    End Property
    

    【讨论】:

      猜你喜欢
      • 2011-08-11
      • 1970-01-01
      • 1970-01-01
      • 2021-03-26
      • 2013-03-05
      • 1970-01-01
      • 2015-07-10
      • 2012-08-15
      • 2017-05-03
      相关资源
      最近更新 更多