« 07.22 なめさせて、のまなざし | ココ | 07.24 カードきた »

2007年7月23日

PropertyGridを操る(4)  このエントリーを含むはてなブックマーク 

PropertyGridコントロールをカスタマイズするコーナーも既に4回目。

  • 「入れ子構造」の形で配列の中身を表示・編集できるようにしたい

  • 「入れ子構造」の形で配列の中身を表示・編集できるようにしたい

コレクションや配列のプロパティの場合、PropertyGridではダイアログが現れて、「追加」「変更」「削除」が各配列の要素に行うことができるようになる(ただし、文字列配列の場合はテキスト編集用ダイアログ:文字列リストの編集ダイアログが出る)。
しかし、このダイアログを出さずに"オブジェクト"のプロパティのように「入れ子」の形式(ExpandableObjectConverter)で表示したい。というときのコード。

<TypeConverter(GetType(ObjectsConverter)), _
Editor(GetType(ObjectsEditor), GetType(UITypeEditor))> _
Public Overridable Property Objects() As Object()
  Get
    Dim _obj() As Object = Me.GetSomeObjects()
    If Not IsNothing(_obj) Then _obj = New Object() {}
    Return _obj
  End Get
  Set(ByVal Value As Object())

  End Set
End Property

<Security.Permissions.PermissionSet(Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
Friend Class ObjectsConverter
  Inherits ExpandableObjectConverter

  Public Overloads Overrides Function GetProperties( _
    ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal value As Object, ByVal attributes() As System.Attribute) As System.ComponentModel.PropertyDescriptorCollection
    Select Case context.PropertyDescriptor.Name.ToLower
    Case "objects"
      Dim s() As Object = value
      If IsNothing(s) Then s = New Object() {}
      Dim c As Integer = s.Length
      Dim props(c - 1) As ObjPropertyDescriptor
      For i As Integer = 0 To c - 1
        props(i) = New ObjPropertyDescriptor(s(i).Text, attributes, s(i))
      Next
      Return New PropertyDescriptorCollection(props)
    End Select

    Return MyBase.GetProperties(context, value, attributes)

  End Function

  Public Overloads Overrides Function GetPropertiesSupported(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
    Return True
  End Function

  Public Overloads Overrides Function CanConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean
    If destinationType Is GetType(String) Then Return True
    Return MyBase.CanConvertTo(context, destinationType)
  End Function

  Public Overloads Overrides Function ConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As System.Type) As Object
    If destinationType Is GetType(String) Then Return ""
    Return MyBase.ConvertTo(context, culture, value, destinationType)
  End Function

  Private Class ObjPropertyDescriptor
    Inherits PropertyDescriptor

    Public Sub New(ByVal name As String, ByVal attrs() As Attribute, Optional ByVal val As Object = Nothing)
      MyBase.New(name, attrs)

      _valProp = val
    End Sub

    Private _valProp As Object

    Public Overrides Function CanResetValue(ByVal component As Object) As Boolean
      Return True
    End Function

    Public Overrides ReadOnly Property ComponentType() As System.Type
      Get
        Return Me.GetType()
      End Get
    End Property

    Public Overrides Function GetValue(ByVal component As Object) As Object
      Return _valProp.SomeProp
    End Function

    Public Overrides ReadOnly Property IsReadOnly() As Boolean
      Get
        Return False
      End Get
    End Property

    Public Overrides ReadOnly Property PropertyType() As System.Type
      Get
        Return GetType(String)
      End Get
    End Property

    Public Overrides Sub ResetValue(ByVal component As Object)
      _valProp.SomeProp = _valProp.DefText
    End Sub

    Public Overrides Sub SetValue(ByVal component As Object, ByVal value As Object)
      _valProp.SomeProp = CStr(value)
      End Sub

    Public Overrides Function ShouldSerializeValue(ByVal component As Object) As Boolean
      Return False
    End Function

  End Class
End Class

<Security.Permissions.PermissionSet(Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
Friend Class ObjectsEditor
  Inherits UITypeEditor

  Public Overloads Overrides Function GetEditStyle(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.Drawing.Design.UITypeEditorEditStyle
    Return UITypeEditorEditStyle.None
  End Function
End Class

PropertyDescriptorの派生クラスObjPropertyDescriptorをプロパティ情報の表示窓として利用し、ExpandableObjectConverterから派生させたObjectsConverterで、オーバーライドしたGetProperties()メソッドの戻り値に表示窓であるObjPropertyDescriptorの配列を返している。実際のプロパティ値変更は、ObjPropertyDescriptorが行っている(引数componentが、対象プロパティの配列を示しているからそれを利用してプロパティ値の変更をすればいいんやけども、今回は1つのPropertyDescriptorに1つのオブジェクトを最初に割り当てているので、別に使う必要がない)。
太字の部分(Editor)を書き加えると、入れ子にしている親分の値に{Object}とか出なくなる(親分のところは編集もできない)。

By ただ at 21:51 カテゴリー ; さんぷるライブラリー , PinMarch Samples , VB, VB .net , プログラミング単語帳 , プログラミング

« 07.22 なめさせて、のまなざし | 07月の記事 | 07.24 カードきた »




トラックバック

このエントリーのトラックバックURL:
http://pinmarch.sakura.ne.jp/mt/mt-tb.cgi/1038