Discussion:
CodeDomSerializer
(too old to reply)
eschneider
2009-03-22 04:43:42 UTC
Permalink
Hello,
Anyone have a sample usage of CodeDomSerializer which
serializes/deserializes a custom constructor?

Thanks,
Eric
eschneider
2009-03-23 05:25:02 UTC
Permalink
Trying to get the designer to serialize my object the way it does the Size
object. "= new Size(100,150)" using contructors.

I think this can be achievied with a type converter?

The code I'm using is below:


Public Class DateTimeCalendarTypeConverter

Inherits TypeConverter

Public Overloads Overrides Function CanConvertFrom(ByVal context As
ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean

If (sourceType.Equals(GetType(String))) Then

Return True

Else

Return MyBase.CanConvertFrom(context, sourceType)

End If

End Function

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

If (destinationType.Equals(GetType(String))) Then

Return True

Else

Return MyBase.CanConvertTo(context, destinationType)

End If

End Function

Public Overloads Overrides Function ConvertFrom(ByVal context As
System.ComponentModel.ITypeDescriptorContext, ByVal culture As CultureInfo,
ByVal value As Object) As Object

If (TypeOf value Is String) Then

If (value Is Nothing) Then

Return MyBase.ConvertFrom(context, culture, value)

End If

Dim str2 As String = value.ToString.Trim

If (str2.Length = 0) Then

Return Nothing

End If

Dim txt As String = CType(value, String)

Dim chars(1) As Char

chars(0) = ",".ToCharArray()(0)

Dim fields() As String = txt.Split(chars)

Try

Dim day As Integer = Integer.Parse(fields(0))

Dim month As Integer = Integer.Parse(fields(1))

Dim year As Integer = Integer.Parse(fields(2))

Dim cal As CalendarSelection =
DirectCast(System.Enum.Parse(GetType(CalendarSelection), fields(3), True),
CalendarSelection)

Return New DateTimeCalendar(day, month, year, cal)

Catch

Throw New InvalidCastException(value.ToString)

End Try

Else

Return MyBase.ConvertFrom(context, culture, value)

End If

End Function

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

If (destinationType Is Nothing) Then Throw New
ArgumentNullException("destinationType")

If TypeOf value Is DateTimeCalendar Then

If (destinationType.Equals(GetType(String))) Then

Return DirectCast(value, DateTimeCalendar).ToTypeConverterString

'Else

' Return MyBase.ConvertTo(context, culture, value, destinationType)

End If

If (destinationType Is GetType(InstanceDescriptor)) Then

Dim dt As DateTimeCalendar = DirectCast(value, DateTimeCalendar)

Dim constructor As ConstructorInfo =
GetType(DateTimeCalendar).GetConstructor(New Type() {GetType(Integer),
GetType(Integer), GetType(Integer), GetType(CalendarSelection)})

If (Not constructor Is Nothing) Then

Return New InstanceDescriptor(constructor, New Object() {dt.Day, dt.Month,
dt.Year, dt.CalendarSelection})

End If

End If

End If

Return MyBase.ConvertTo(context, culture, value, destinationType)

End Function

Public Overrides Function CreateInstance(ByVal context As
ITypeDescriptorContext, ByVal propertyValues As IDictionary) As Object

If (propertyValues Is Nothing) Then

Throw New ArgumentNullException("propertyValues")

End If

Dim obj2 As Object = propertyValues.Item("Day")

Dim obj3 As Object = propertyValues.Item("Month")

Dim obj4 As Object = propertyValues.Item("Year")

Dim obj5 As Object = propertyValues.Item("CalendarSelection")

'If ((((obj2 Is Nothing) OrElse (obj3 Is Nothing)) OrElse ((obj4 Is Nothing)
OrElse (obj5 Is Nothing))) OrElse ((Not TypeOf obj2 Is Integer OrElse Not
TypeOf obj3 Is Integer) OrElse (Not TypeOf obj4 Is Integer OrElse Not TypeOf
obj5 Is Integer))) Then

' Throw New ArgumentException("PropertyValueInvalidEntry")

'End If

Return New DateTimeCalendar(CInt(obj2), CInt(obj3), CInt(obj4),
DirectCast(System.Enum.Parse(GetType(CalendarSelection), obj5.ToString,
True), CalendarSelection))

End Function

Public Overrides Function GetCreateInstanceSupported(ByVal context As
ITypeDescriptorContext) As Boolean

Return True

End Function



Public Overrides Function GetPropertiesSupported(ByVal context As
ITypeDescriptorContext) As Boolean

Return True

End Function

Public Overrides Function GetProperties(ByVal context As
ITypeDescriptorContext, ByVal value As Object, ByVal attributes As
Attribute()) As PropertyDescriptorCollection

Return TypeDescriptor.GetProperties(GetType(DateTimeCalendar),
attributes).Sort(New String() {"Day", "Month", "Year", "CalendarSelection"})

End Function

End Class


<Serializable()> _

<TypeConverter(GetType(DateTimeCalendarTypeConverter))> _

Public Class DateTimeCalendar

Private m_Year As Integer

Private m_Month As Integer

Private m_Day As Integer

Private m_CalendarSelection As CalendarSelection =
CalendarSelection.GregorianCalendar

Private m_Calendar As Calendar

Public Sub New()

End Sub

Public Sub New(ByVal day As Integer, ByVal month As Integer, ByVal year As
Integer, ByVal calendarType As CalendarSelection)

m_Day = day

m_Month = month

m_Year = year

m_CalendarSelection = calendarType

m_Calendar = Me.CreateCalendar

End Sub

Public ReadOnly Property Calendar() As Calendar

Get

Return m_Calendar

End Get

End Property

''' <summary>

''' Indicates the calender type to use.

''' </summary>

''' <value>CalendarSelection.</value>

''' <returns>CalendarSelection.</returns>

''' <remarks></remarks>

<Category("Behavior")> _

<Description("Indicates the calender type to use.")> _

Public Property CalendarSelection() As CalendarSelection

Get

Return m_CalendarSelection

End Get

Set(ByVal value As CalendarSelection)

m_CalendarSelection = value

End Set

End Property

<Category("Data")> _

Public Property Year() As Integer

Get

Return m_Year

End Get

Set(ByVal value As Integer)

m_Year = value

End Set

End Property

<Category("Data")> _

Property Month() As Integer

Get

Return m_Month

End Get

Set(ByVal value As Integer)

m_Month = value

End Set

End Property

<Category("Data")> _

Property Day() As Integer

Get

Return m_Day

End Get

Set(ByVal value As Integer)

m_Day = value

End Set

End Property

Public Function ToDateTime() As DateTime

Return New DateTime(Me.Year, Me.Month, Me.Day, Me.Calendar)

End Function

Protected Overridable Function CreateCalendar() As Calendar

Select Case m_CalendarSelection

Case CalendarSelection.ChineseLunisolarCalendar

#If MonoBuild Then

Return New GregorianCalendar

#Else

Return New ChineseLunisolarCalendar 'Mono issue

#End If

Case CalendarSelection.GregorianCalendar

Return New GregorianCalendar

Case CalendarSelection.HebrewCalendar

Return New HebrewCalendar

Case CalendarSelection.HijriCalendar

Return New HijriCalendar

Case CalendarSelection.JapaneseCalendar

Return New JapaneseCalendar

Case CalendarSelection.JapaneseLunisolarCalendar

#If MonoBuild Then

Return New GregorianCalendar

#Else

Return New JapaneseLunisolarCalendar 'Mono issue

#End If

Case CalendarSelection.JulianCalendar

Return New JulianCalendar

Case CalendarSelection.KoreanCalendar

Return New KoreanCalendar

Case CalendarSelection.KoreanLunisolarCalendar

#If MonoBuild Then

Return New GregorianCalendar

#Else

Return New KoreanLunisolarCalendar 'Mono issue

#End If

Case CalendarSelection.PersianCalendar

Return New PersianCalendar

Case CalendarSelection.TaiwanCalendar

Return New TaiwanCalendar

Case CalendarSelection.TaiwanLunisolarCalendar

#If MonoBuild Then

Return New GregorianCalendar

#Else

Return New TaiwanLunisolarCalendar 'Mono issue

#End If

Return New GregorianCalendar

Case CalendarSelection.ThaiBuddhistCalendar

Return New ThaiBuddhistCalendar

Case CalendarSelection.UmAlQuraCalendar

Return New UmAlQuraCalendar

Case Else

Return New GregorianCalendar

End Select

End Function

Public Function ToTypeConverterString() As String

Dim sb As New System.Text.StringBuilder

sb.Append(Me.Day.ToString(System.Globalization.CultureInfo.CurrentCulture))

sb.Append(",")

sb.Append(Me.Month.ToString(System.Globalization.CultureInfo.CurrentCulture))

sb.Append(",")

sb.Append(Me.Year.ToString(System.Globalization.CultureInfo.CurrentCulture))

sb.Append(",")

sb.Append(Me.CalendarSelection.ToString())

Return sb.ToString

End Function

End Class
Post by eschneider
Hello,
Anyone have a sample usage of CodeDomSerializer which
serializes/deserializes a custom constructor?
Thanks,
Eric
Linda Liu[MSFT]
2009-03-23 09:48:19 UTC
Permalink
Hi Eric,

Yes, you're right. You need to use type converter to participate in code
generation through the use of instance descriptors.

The following MSDN document shows a sample on this:

http://msdn.microsoft.com/en-us/library/system.componentmodel.design.seriali
zation.instancedescriptor.aspx

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
***@microsoft.com.

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
eschneider
2009-03-23 15:36:23 UTC
Permalink
Thanks, for the example.

Can you see any problems with the code I included?

I can't seem to get it to work.

Thanks,
Eric
Post by Linda Liu[MSFT]
Hi Eric,
Yes, you're right. You need to use type converter to participate in code
generation through the use of instance descriptors.
http://msdn.microsoft.com/en-us/library/system.componentmodel.design.seriali
zation.instancedescriptor.aspx
Hope this helps.
If you have any question, please feel free to let me know.
Sincerely,
Linda Liu
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Linda Liu[MSFT]
2009-03-24 04:36:11 UTC
Permalink
Hi Eric,

Thank you for your prompt response!

Your sample code contains a CalendarSelection type, whose definition is not
included in the sample code. So the sample code couldn't pass compilation
in my project. I simplied your sample code as follows and it works fine.

Imports System.ComponentModel
Imports System.Globalization
Imports System.Reflection
Imports System.ComponentModel.Design.Serialization

Public Class DateTimeCalendarTypeConverter
Inherits TypeConverter

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

If (destinationType Is GetType(InstanceDescriptor)) Then
Return True
End If
Return MyBase.CanConvertTo(context, destinationType)
End Function


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

If (destinationType Is GetType(InstanceDescriptor)) Then
Dim dt As DateTimeCalendar = CType(value, DateTimeCalendar)
Dim ci As ConstructorInfo =
GetType(DateTimeCalendar).GetConstructor(New Type() {GetType(Integer),
GetType(Integer), GetType(Integer)})
Return New InstanceDescriptor(ci, New Object() {dt.Day,
dt.Month, dt.Year})
End If

Return MyBase.ConvertTo(context, culture, value, destinationType)

End Function

End Class

<Serializable()> _
<TypeConverter(GetType(DateTimeCalendarTypeConverter))> _
Public Class DateTimeCalendar
Private m_Year As Integer
Private m_Month As Integer
Private m_Day As Integer

Public Sub New()

End Sub

Public Sub New(ByVal day As Integer, ByVal month As Integer, ByVal year
As Integer)
m_Day = day
m_Month = month
m_Year = year
End Sub

<Category("Data")> _
Public Property Year() As Integer
Get
Return m_Year
End Get

Set(ByVal value As Integer)
m_Year = value
End Set

End Property

<Category("Data")> _
Property Month() As Integer
Get
Return m_Month
End Get

Set(ByVal value As Integer)
m_Month = value
End Set

End Property

<Category("Data")> _
Property Day() As Integer
Get
Return m_Day
End Get

Set(ByVal value As Integer)
m_Day = value
End Set
End Property
End Class

'I add a UserControl which contains a property of type DateTimeCalendar
Public Class UserControl1
Private calendar As DateTimeCalendar

Public Sub New()

' This call is required by the Windows Form Designer.
InitializeComponent()

' Add any initialization after the InitializeComponent() call.
calendar = New DateTimeCalendar(2, 3, 2009)
End Sub
Public Property MyCalendar() As DateTimeCalendar
Get
Return calendar
End Get
Set(ByVal value As DateTimeCalendar)
calendar = value
End Set
End Property
End Class

Build the project and add the UserControl1 onto a form. I see the
MyCalendar property of the UserControl is initialized in the
InitializeComponent method as follows:
Me.UserControl11.MyCalendar = New WindowsApplication1.DateTimeCalendar(2,
3, 2009)

If the property of type DateTimeCalendar isn't serialized in the
InitializeComponent method, have a try closing the Visual Studio and
opening it again.

Hope this helps.

Sincerely,
Linda Liu
Microsoft Online Community Support
eschneider
2009-03-24 05:51:02 UTC
Permalink
Hi, Linda

The issue was here:
Public Overloads Overrides Function CanConvertTo(ByVal context As
ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean

If (destinationType Is GetType(InstanceDescriptor)) Then
Return True
End If
Return MyBase.CanConvertTo(context, destinationType)
End Function

My code did not return true on InstanceDescriptor.


Thanks,
Eric
Post by Linda Liu[MSFT]
Hi Eric,
Thank you for your prompt response!
Your sample code contains a CalendarSelection type, whose definition is not
included in the sample code. So the sample code couldn't pass compilation
in my project. I simplied your sample code as follows and it works fine.
Imports System.ComponentModel
Imports System.Globalization
Imports System.Reflection
Imports System.ComponentModel.Design.Serialization
Public Class DateTimeCalendarTypeConverter
Inherits TypeConverter
Public Overloads Overrides Function CanConvertTo(ByVal context As
ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean
If (destinationType Is GetType(InstanceDescriptor)) Then
Return True
End If
Return MyBase.CanConvertTo(context, destinationType)
End Function
Public Overloads Overrides Function ConvertTo(ByVal context As
ITypeDescriptorContext, ByVal culture As CultureInfo, ByVal value As
Object, ByVal destinationType As System.Type) As Object
If (destinationType Is GetType(InstanceDescriptor)) Then
Dim dt As DateTimeCalendar = CType(value, DateTimeCalendar)
Dim ci As ConstructorInfo =
GetType(DateTimeCalendar).GetConstructor(New Type() {GetType(Integer),
GetType(Integer), GetType(Integer)})
Return New InstanceDescriptor(ci, New Object() {dt.Day,
dt.Month, dt.Year})
End If
Return MyBase.ConvertTo(context, culture, value, destinationType)
End Function
End Class
<Serializable()> _
<TypeConverter(GetType(DateTimeCalendarTypeConverter))> _
Public Class DateTimeCalendar
Private m_Year As Integer
Private m_Month As Integer
Private m_Day As Integer
Public Sub New()
End Sub
Public Sub New(ByVal day As Integer, ByVal month As Integer, ByVal year
As Integer)
m_Day = day
m_Month = month
m_Year = year
End Sub
<Category("Data")> _
Public Property Year() As Integer
Get
Return m_Year
End Get
Set(ByVal value As Integer)
m_Year = value
End Set
End Property
<Category("Data")> _
Property Month() As Integer
Get
Return m_Month
End Get
Set(ByVal value As Integer)
m_Month = value
End Set
End Property
<Category("Data")> _
Property Day() As Integer
Get
Return m_Day
End Get
Set(ByVal value As Integer)
m_Day = value
End Set
End Property
End Class
'I add a UserControl which contains a property of type DateTimeCalendar
Public Class UserControl1
Private calendar As DateTimeCalendar
Public Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
calendar = New DateTimeCalendar(2, 3, 2009)
End Sub
Public Property MyCalendar() As DateTimeCalendar
Get
Return calendar
End Get
Set(ByVal value As DateTimeCalendar)
calendar = value
End Set
End Property
End Class
Build the project and add the UserControl1 onto a form. I see the
MyCalendar property of the UserControl is initialized in the
Me.UserControl11.MyCalendar = New WindowsApplication1.DateTimeCalendar(2,
3, 2009)
If the property of type DateTimeCalendar isn't serialized in the
InitializeComponent method, have a try closing the Visual Studio and
opening it again.
Hope this helps.
Sincerely,
Linda Liu
Microsoft Online Community Support
Linda Liu[MSFT]
2009-03-25 03:03:44 UTC
Permalink
Hi Eric,

Thank you for your quick response!

Have you copy all the sample code in my last reply to your project? The
sample code works fine on my side.

If the problem still exists, please reproduce it in a simple project and
send the project to me. My email address is v-***@microsoft.com.

Sincerely,
Linda Liu
Microsoft Online Community Support

Loading...