Struttura System.Drawing.Font e XmlSerializer
Se si è provato a serializzare in XML la struttura System.Drawing.Font 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.Font che vogliamo serializzare possiamo usare definire una seconda proprietà che non tipo System.Drawing.Font, ma ad esempio di tipo stringa che andrà a impostare la proprietà System.Drawing.Font tramite il metodo System.Drawing.FontConverter.ConvertFromInvariantString. La proprietà System.Drawing.Font 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 DefaultOutputConsoleFont As System.Drawing.Font = System.Drawing.SystemFonts.DefaultFont
Private outputConsoleFontValue As System.Drawing.Font = PowerTraySettings.DefaultOutputConsoleFont
<System.Xml.Serialization.XmlIgnore()>
<System.ComponentModel.Category(GeneralCategory)>
<System.ComponentModel.DisplayName(“Output console font”)>
Public Property OutputConsoleFont As System.Drawing.FontGet
Return Me.outputConsoleFontValue
End Get
Set(value As System.Drawing.Font)
Me.outputConsoleFontValue = value
End SetEnd Property
Public Function ShouldSerializeOutputConsoleFont() As Boolean
Dim fc As New System.Drawing.FontConverter
Return Not (fc.ConvertToInvariantString(Me.outputConsoleFontValue) = fc.ConvertToInvariantString(PowerTraySettings.DefaultOutputConsoleFont))End Function
Public Sub ResetOutputConsoleFont()
Me.outputConsoleFontValue = PowerTraySettings.DefaultOutputConsoleFont
End Sub
<System.ComponentModel.Browsable(False)>
Public Property OutputConsoleFontInvariantString As StringGet
Dim fc As New System.Drawing.FontConverter
Return fc.ConvertToInvariantString(Me.outputConsoleFontValue)End Get
Set(value As String)‘Il confronto eseguito con il metodo Equals restisce False per che la Proprietà GdiCharSet differisce
‘https://docs.microsoft.com/en-us/dotnet/api/system.drawing.font.equals
Dim fc As New System.Drawing.FontConverter
Me.outputConsoleFontValue = DirectCast(fc.ConvertFromInvariantString(value), System.Drawing.Font)End Set
End Property
Public Function ShouldSerializeOutputConsoleFontInvariantString() As Boolean
Return Me.ShouldSerializeOutputConsoleFont()
End Function