Struttura System.Drawing.Color e XmlSerializer

Se si è provato a serializzare in XML la struttura System.Drawing.Color tramite un oggetto della classe System.Xml.Serialization.XmlSerializer si sarà notato che questa non viene serializzata correttamente. Il motivo dipende dal fatto che l’XmlSerializer richiede che l’oggetto da serializzare abbia un costruttore pubblico senza parametri come indicato nella KB330592 Error message when you serialize a class by using the XMLSerializer class: “System.InvalidOperationException”.

La classe System.Drawing.Color ha un costruttore senza parametri, ma privato e non pubblico.

Quindi se in una classe abbiamo una proprietà di tipo System.Drawing.Color che vogliamo serializzare possiamo usare definire una seconda proprietà che non tipo System.Drawing.Color, ma ad esempio di tipo stringa che andrà a impostare la proprietà System.Drawing.Color tramite il metodo System.Drawing.ColorTranslator.FromHtml. La proprietà System.Drawing.Color sarà quella che imposteremo a design time ad esempio tramite un PropertyGrid, ma non verrà serializzata impostando su di essa l’attributo System.Xml.Serialization.XmlIgnore. La proprietà stringa sarà invece la proprietà che verrà serializzata, ma per evitare confusioni non verrà visualizzata a design time decorandola con l’attributo System.ComponentModel.Browsable.

Di seguito un esempio tratto dall’applicazione .NET WinForms PowerTray che sto sviluppando a tempo perso e che ha l’obbiettivo di poter eseguire script PowerShell e di visualizzare l’output quando lo si desidera tramite una un’icona nella tray bar.

Public Shared ReadOnly Property DefaultOutputConsoleBackColor As System.Drawing.Color = System.Drawing.Color.FromArgb(1, 36, 86)

 

Private outputConsoleBackColorValue As System.Drawing.Color = PowerTraySettings.DefaultOutputConsoleBackColor

 

<System.Xml.Serialization.XmlIgnore()>

<System.ComponentModel.Category(GeneralCategory)>

<System.ComponentModel.DisplayName(“Output console backcolor”)>

Public Property OutputConsoleBackColor As System.Drawing.Color

Get

Return Me.outputConsoleBackColorValue

End Get

Set(value As System.Drawing.Color)

Me.outputConsoleBackColorValue = value

End Set

End Property

 

Public Function ShouldSerializeOutputConsoleBackColor() As Boolean

Return Not Me.outputConsoleBackColorValue.Equals(DefaultOutputConsoleBackColor)

End Function

 

Public Sub ResetOutputConsoleBackColor()

Me.OutputConsoleBackColor = DefaultOutputConsoleBackColor

End Sub

 

<System.ComponentModel.Browsable(False)>

Public Property OutputConsoleBackColorHtml As String

Get

Return System.Drawing.ColorTranslator.ToHtml(Me.outputConsoleBackColorValue)

End Get

Set(value As String)

Me.outputConsoleBackColorValue = System.Drawing.ColorTranslator.FromHtml(value)

End Set

End Property

 

Public Function ShouldSerializeOutputConsoleBackColorHtml() As Boolean

Return Me.ShouldSerializeOutputConsoleBackColor()

End Function