Feedback

C# - Type Color serialisieren und deserialisieren

Veröffentlicht von am 12/8/2008
(2 Bewertungen)
Aus welchem Grund auch immer hat Microsoft für den Typ Color keine Serialisierung implementiert. (Bei anderen struct Typen, wie Point oder Size, die in etwa gleich wichtig und häufig verwendeten werden, haben sie das nicht vergessen)

Damit stellt sich das Problem, dass ein Workaround für die De-/Serialisierung verwendet werden muss, damit Farben z.B. in Configurationsdateien abgelegt und wieder eingelesen werden können.

Meine Lösung implementiert eine Extension für den Typ string, damit die Farbangaben als Namen wie in der Klasse Color oder als ARGB Wert verwendet werden können.

Die Anwendung für ein zu serialisierendes Property in einer Datenstruktur ist sehr simpel und sieht wie folgt aus:


[XmlIgnore]
public Color MyColor { get; set; }
[EditorBrowsable( EditorBrowsableState.Never )]
public string MyColorXml
{
get { return MyColor.Name; }
set { MyColor = value.ToColor(); }
}

/// <summary>
/// Returns a <see cref="Color"/> object based on its color name. The 'color name' 
/// is of the color from <see cref="Color.KnownColor"/> or a hexadecimal value as 
/// returned by <see cref="Color.Name"/> (hex format: 'aarrggbb').
/// <para>
/// This can be very easily used, for example, for XML serialisation 
/// where type <see cref="Color"/> can not be used:
/// <pre>
/// [XmlIgnore]
/// public Color MyColor { get; set; }
/// [EditorBrowsable( EditorBrowsableState.Never )]
/// public string MyColorXml
/// {
///     get { return MyColor.Name; }
///     set { MyColor = value.ToColor(); }
/// }
/// </pre>
/// </para>
/// </summary>
/// <returns>A <see cref="Color"/> object.</returns>
public static Color ToColor( this string thisValue )
{
    Color color = Color.FromName( thisValue );
    if( !color.IsKnownColor )
    {
        try
        {
            // try to convert from hex format: aarrggbb
            int iResult = Convert.ToInt32( thisValue, 16 );
            color = Color.FromArgb( iResult >> 24 & 0xff, iResult >> 16 & 0xff, iResult >> 8 & 0xff, iResult & 0xff );
        }
        catch { }
    }
    return color;
}



Abgelegt unter Color, Serialisierung, Extension.

4 Kommentare zum Snippet

Günther Foidl schrieb am 12/8/2008:
Die Color-Struktur ist mit dem Serializable-Attribut "dekoriert". Insofern lässt sie sich auch serialisieren/deserialisiern (auch in XML).

Für die Konvertierung könnte auch ein ColorConverter verwendet werden. Dennoch finde ich die Bitverschiebungen cool ;)
infero schrieb am 12/8/2008:
Mit Serializable-Attribute alleine ist noch nicht definiert, dass die Implementierung auch sauber funktioniert.

Mit folgendem Code wird keine Farbe serialisiert (es entsteht nur ein leeres Tag):

[Serializable]
public class ABC
{
public Color MyColor { get; set; }

public ABC()
{
MyColor = Color.Blue;
}
}

private void Form1_Load( object sender, EventArgs e )
{
string strFileName = @"C:\temp\Data.xml";

using( TextWriter writer = new StreamWriter( strFileName ) )
{
ABC data = new ABC();
Console.WriteLine( "Before serialization: MyColor = " + data.MyColor.ToString() );
XmlSerializer serializer = new XmlSerializer( data.GetType() );
serializer.Serialize( writer, data );
}

using( TextReader reader = new StreamReader( strFileName ) )
{
XmlSerializer serializer = new XmlSerializer( typeof( ABC ) );
ABC data = (ABC)serializer.Deserialize( reader );
Console.WriteLine( "After serialization: MyColor = " + data.MyColor.ToString() );
}
}


Die Ausgabe ist dabei:
Before serialization: MyColor = Color [Blue]
After serialization: MyColor = Color [Empty]
Günther Foidl schrieb am 12/9/2008:
Aha, schade. Interessant aber dass es bei den Settings (mit Desinger ertellt) problemlos funktioniert.
infero schrieb am 12/9/2008:
Das ist nicht weiter verwunderliche, denn die Settings (mit dem Designer) funktionieren ganz anders als die 'normale' Serialisierung.
 

Logge dich ein, um hier zu kommentieren!