C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: Webカスタムコントロールのaspxからの復元


(過去ログ 103 を表示中)

[トピック内 2 記事 (1 - 2 表示)]  << 0 >>

■61529 / inTopicNo.1)  Webカスタムコントロールのaspxからの復元
  
□投稿者/ ひろ (10回)-(2011/08/18(Thu) 16:13:01)

分類:[ASP.NET (VB)] 

.netフレームワーク 1.1
VS2003
ASP.NET(VB)

いつもお世話になっております。
おかげさまで、プロパティをaspxに保存するところまで
たどり着きました。

aspxにはこのように記録されるようになりました。
<cc2:MyControl id="MyControl1" title="TEST" runat="server">
    <ControlData1 Title="MyTitle" DataList="AAA|0|BBB|1"></ControlData1>
</cc2:MyControl></form>

しかし、このプロジェクトを閉じて開くと、カスタムコントロールが
エラーになってしまいます。
エラーメッセージは
「''をプロパティ'ControlData1'で設定できませんでした。」
です。

aspxファイルに保存されている内容からカスタムコントロールを
復元するにはどうしたら良いのでしょうか?



以下ソース
<Designer("MyControlDesigner"), ParseChildren(True), ToolboxData("<{0}:MyControl runat=server></{0}:MyControl>")>
Public Class MyControl
    Inherits System.Web.UI.WebControls.WebControl

    Protected _mControlData1 As New ControlData

    <Bindable(True), Category("Appearance"), DefaultValue(""), _
                PersistenceMode(PersistenceMode.InnerProperty)> _
    Public Property ControlData1() As ControlData
        Get
            Return _mControlData1
        End Get
        Set(ByVal Value As ControlData)
            _mControlData1 = Value
        End Set
    End Property

    ・・・

End Class


<Serializable(), _
 TypeConverter(GetType(ControlDataConverter))> _
Public Class ControlData
    Protected _mTitle As String
    Protected _mDataList As New ArrayList

    Public Property Title() As String
        Get
            Return _mTitle
        End Get
        Set(ByVal Value As String)
            _mTitle = Value
        End Set
    End Property

    <Editor(GetType(ControlDataEditor), GetType(UITypeEditor)), _
                TypeConverter(GetType(DataListConverter))> _
    Public Property DataList() As ArrayList
        Get
            Return _mDataList
        End Get
        Set(ByVal Value As ArrayList)
            _mDataList = Value
        End Set
    End Property
End Class


Public Class ControlDataConverter
    Inherits ExpandableObjectConverter

    Public Overloads Overrides Function CanConvertTo( _
        ByVal context As ITypeDescriptorContext, _
        ByVal destinationType As Type) As Boolean

        If destinationType Is GetType(ControlData) Then
            Return True
        End If

        Return MyBase.CanConvertTo(context, destinationType)
    End Function

    Public Overloads Overrides Function ConvertTo( _
        ByVal context As ITypeDescriptorContext, _
        ByVal culture As System.Globalization.CultureInfo, _
        ByVal value As Object, _
        ByVal destinationType As Type) As Object

        If destinationType Is GetType(String) And TypeOf value Is ControlData Then
            Dim gd As ControlData = CType(value, ControlData)
            Dim bf As New BinaryFormatter
            Dim ms As New MemoryStream

            bf.Serialize(ms, gd)
            Return BitConverter.ToString(ms.ToArray)
        End If
        Return MyBase.ConvertTo(context, culture, value, destinationType)
    End Function

    Public Overloads Overrides Function CanConvertFrom( _
        ByVal context As ITypeDescriptorContext, _
        ByVal sourceType As Type) As Boolean
        If sourceType Is GetType(String) Then
            Return True
        End If
        Return MyBase.CanConvertFrom(context, sourceType)
    End Function

    Public Overloads Overrides Function ConvertFrom( _
        ByVal context As ITypeDescriptorContext, _
        ByVal culture As System.Globalization.CultureInfo, _
        ByVal value As Object) As Object
        If TypeOf value Is String Then
            Dim hexChars As String() = value.ToString().Split(New Char() {"-"c})
            Dim gd As New ControlData
            Dim bf As New BinaryFormatter
            Dim ms As New MemoryStream
            Dim i As Integer

            For i = 0 To UBound(hexChars)
                ms.WriteByte(Convert.ToByte(hexChars(i), 16))
            Next

            gd = CType(bf.Deserialize(ms), ControlData)

            Return gd
        End If
        Return MyBase.ConvertFrom(context, culture, value)
    End Function
End Class


Public Class ControlDataEditor
    Inherits CollectionEditor

    Public Sub New(ByVal type As System.Type)
        MyBase.New(type)
    End Sub

    Protected Overloads Overrides Function CanSelectMultipleInstances() As Boolean
        Return False
    End Function

    Protected Overloads Overrides Function CreateCollectionItemType() As System.Type
        Return GetType(ControlDataPoint)
    End Function

    Protected Overloads Overrides Function CreateInstance(ByVal itemType As System.Type) As Object
        If itemType Is GetType(ControlDataPoint) Then
            Return New ControlDataPoint
        End If

        Return Nothing
    End Function
End Class


<Serializable()> _
Public Class ControlDataPoint
    Protected _mX As String
    Protected _mY As Decimal

    Public Property X() As String
        Get
            Return _mX
        End Get
        Set(ByVal Value As String)
            _mX = Value
        End Set
    End Property

    Public Property Y() As Decimal
        Get
            Return _mY
        End Get
        Set(ByVal Value As Decimal)
            _mY = Value
        End Set
    End Property
End Class

引用返信 編集キー/
■61564 / inTopicNo.2)  Re[1]: Webカスタムコントロールのaspxからの復元
□投稿者/ ひろ (11回)-(2011/08/19(Fri) 17:52:49)
解決しました。

Controlを継承するようにして、
クラスのConverterをはずし、
プロパティをReadOnlyにしたところ、
aspxの記述内容がコントロールに反映されました。

試行錯誤で実現できてますが、理解はできていません。

どこかにわかりやすい解説は無いものでしょうか?


以下、復元できるようになったソースです。
<Designer("MyControlDesigner"), ParseChildren(True), ToolboxData("<{0}:MyControl runat=server></{0}:MyControl>")>
Public Class MyControl
    Inherits System.Web.UI.WebControls.WebControl

    Protected _mControlData1 As New ControlData

    <Bindable(True), Category("Appearance"), DefaultValue(""), _
                DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), _
                PersistenceMode(PersistenceMode.InnerProperty)> _
    Public ReadOnly Property ControlData1() As ControlData
        Get
            Return _mControlData1
        End Get
    End Property

    ・・・

End Class


<Serializable(), Browsable(True)> _
Public Class ControlData
    Inherits System.Web.UI.Control

    Protected _mTitle As String
    Protected _mDataList As New ArrayList

    <NotifyParentProperty(True), Browsable(True)> _
    Public Property Title() As String
        Get
            Return _mTitle
        End Get
        Set(ByVal Value As String)
            _mTitle = Value
        End Set
    End Property

    <Editor(GetType(ControlDataEditor), GetType(UITypeEditor)), _
                TypeConverter(GetType(DataListConverter)), _
                NotifyParentProperty(True), Browsable(True)> _
    Public Property DataList() As ArrayList
        Get
            Return _mDataList
        End Get
        Set(ByVal Value As ArrayList)
            _mDataList = Value
        End Set
    End Property
End Class


Protected Class DataListConverter
    Inherits ExpandableObjectConverter

    Public Overloads Overrides Function CanConvertTo( _
        ByVal context As ITypeDescriptorContext, _
        ByVal destinationType As Type) As Boolean

        If destinationType Is GetType(ArrayList) Then
            Return True
        End If

        Return MyBase.CanConvertTo(context, destinationType)
    End Function

    Public Overloads Overrides Function ConvertTo( _
        ByVal context As ITypeDescriptorContext, _
        ByVal culture As System.Globalization.CultureInfo, _
        ByVal value As Object, _
        ByVal destinationType As Type) As Object

        If destinationType Is GetType(String) And TypeOf value Is ArrayList Then
            Dim dl As ArrayList = CType(value, ArrayList)
            Dim gdp As ControlDataPoint
            Dim sb As New System.Text.StringBuilder

            For Each gdp In dl
                sb.Append(gdp.X).Append("|").Append(gdp.Y).Append("|")
            Next

            If sb.Length > 0 Then
                Return sb.ToString(0, sb.Length - 1)
            Else
                Return ""
            End If
        End If
        Return MyBase.ConvertTo(context, culture, value, destinationType)
    End Function

    Public Overloads Overrides Function CanConvertFrom( _
        ByVal context As ITypeDescriptorContext, _
        ByVal sourceType As Type) As Boolean
        If sourceType Is GetType(String) Then
            Return True
        End If
        Return MyBase.CanConvertFrom(context, sourceType)
    End Function

    Public Overloads Overrides Function ConvertFrom( _
        ByVal context As ITypeDescriptorContext, _
        ByVal culture As System.Globalization.CultureInfo, _
        ByVal value As Object) As Object
        If TypeOf value Is String Then
            Dim ss As String() = value.ToString().Split(New Char() {"|"c})
            Dim dl As New ArrayList
            Dim i As Integer
            Dim gdp As ControlDataPoint

            For i = 0 To UBound(ss) Step 2
                gdp = New ControlDataPoint(ss(i), Decimal.Parse(ss(i + 1)))
                dl.Add(gdp)
            Next

            Return dl
        End If
        Return MyBase.ConvertFrom(context, culture, value)
    End Function
End Class


Public Class ControlDataEditor
    Inherits CollectionEditor

    Public Sub New(ByVal type As System.Type)
        MyBase.New(type)
    End Sub

    Protected Overloads Overrides Function CanSelectMultipleInstances() As Boolean
        Return False
    End Function

    Protected Overloads Overrides Function CreateCollectionItemType() As System.Type
        Return GetType(ControlDataPoint)
    End Function

    Protected Overloads Overrides Function CreateInstance(ByVal itemType As System.Type) As Object
        If itemType Is GetType(ControlDataPoint) Then
            Return New ControlDataPoint
        End If

        Return Nothing
    End Function
End Class


<Serializable()> _
Public Class ControlDataPoint
    Protected _mX As String
    Protected _mY As Decimal

    Public Property X() As String
        Get
            Return _mX
        End Get
        Set(ByVal Value As String)
            _mX = Value
        End Set
    End Property

    Public Property Y() As Decimal
        Get
            Return _mY
        End Get
        Set(ByVal Value As Decimal)
            _mY = Value
        End Set
    End Property
End Class

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -