Entwickler-Ecke

IO, XML und Registry - Font in xml datei schreiben und auslesen funktioniert nicht


Chiyoko - Di 08.06.10 16:12
Titel: Font in xml datei schreiben und auslesen funktioniert nicht
Huhu ,

mein neues Problem ist das setzen der Font eigenschaften und ein/auslesen in eine xml datei.

Mein bisheriger Ansatz war so:


C#-Quelltext
1:
2:
3:
4:
// in die config schreiben:
//....
new XElement("Label_date_font", Label_date.Font),
//...



Das auskommentierte ganz unten ist die Variante 2 (FontConverter)

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
// Config auslesen, im Prinzip wie bei Color.:
// 2 Varianten, ...die "Fontconverter"variante verursacht keinen Fehler, funktioniert 
// aber nicht, TypConverter gibt error meldung.
// ehrlich gesagt ist mir ersteres lieber, aber aus welchen Gruienden auch immer, wird 
// der Font nicht gesetzt.


       string configPfad = Path.Combine(Application.StartupPath, @"config.xml");
            if (File.Exists(configPfad))
            {
                XDocument xDocument = XDocument.Load(configPfad);
                ColorConverter convertColor = new ColorConverter();
                //FontConverter convertFont = new FontConverter();
                TypeConverter converter = new TypeConverter();

                var xdocselect = xDocument.XPathSelectElements("Configuration");

                foreach (var Xselectel in xdocselect)
                {
                    Label_date.ForeColor = (Color)convertColor.ConvertFromString(Xselectel.Element("Label_date_color").Value);
                    Label_time.ForeColor = (Color)convertColor.ConvertFromString(Xselectel.Element("Label_time_color").Value);

                    Font font1 = converter.ConvertFromString(Xselectel.Element("Label_date_font").Value);
                    Font font2 = converter.ConvertFromString(Xselectel.Element("Label_time_font").Value);
                    string fontName1 = converter.ConvertFromString(font1);
                    string fontName2 = converter.ConvertFromString(font2);
                    Label_date.Font = fontName1;
                    Label_time.Font = fontName2;

                    // Label_date.Font = convertFont.ConvertFromString(Xselectel.Element("Label_time_color").Value);
                }
            }
            else
            {
                ersterStart = true;     // Config exestiert nicht
                return;
            }



Auch das funktioniert nicht:


C#-Quelltext
1:
Font f =(Font)TypeDescriptor.GetConverter(typeof(Font)).ConvertFromString("Microsoft Sans Serif; 8,25pt");                    


danielf - Di 08.06.10 16:21

Hallo,

warum verwendest du nicht die Settings um solche Informationen abzulegen?

Ansonsten kannst du den XmlSerializer versuchen oder einfach den FontFamily Name abspeichern und eine neue Font instanz davon generieren (evlt. noch die Font-Size).

Gruß


Chiyoko - Di 08.06.10 16:34

Ich kam mit den Settings nicht klar^^(wenn du das meinst, was ich denke).
Und mittlerweile habe ich mich an Xml gewoehnt:)

Und danke, ich teste trotzdem mal ein wenig durch.

ABER:....wieso funktioniert dann ColorConverter convertColor = new ColorConverter();?


danielf - Di 08.06.10 16:44

Nun ja, also du speicherst ja nur Label_date.Font ... welches die ToString() Methode aufruft.. so hast du kaum informationen - du musst dir für das Speichern genau soviel "mühe geben" wie beim Laden.

Am Besten du versuchst den XmlSerializer, wenn der nicht geht, kannst du es noch immer händisch machen. Und dann halt alle informationen: new XElement("Label_Date_font", Label_Date.Font) ist quark.


Chiyoko - Di 08.06.10 16:47

Jap danke, genau den Gedanken hat ich auch gerade.

Ich setze alle Elemente einzeln.
So hab ich auch etwas mehr Kontrolle^^
Ich muss mal schauen, was man alles ausblenden kann.
Denn es reicht ja der Schriftname, die Schriftgroesse und und den Schriftschnitt auszugeben.
(Fuer meine Zwecke)..


Kha - Di 08.06.10 21:10

user profile iconChiyoko hat folgendes geschrieben Zum zitierten Posting springen:
Auch das funktioniert nicht:


C#-Quelltext
1:
Font f =(Font)TypeDescriptor.GetConverter(typeof(Font)).ConvertFromString("Microsoft Sans Serif; 8,25pt");                    
Sollte es aber. Was sagt denn die Errormeldung, die kein Fehler ist :gruebel: ?


Chiyoko - Di 08.06.10 21:46

Habs geloescht,...
Aber ich mach s nochmal neu.


Das schreibt sich bei "Font" in die xml datei:

XML-Daten
1:
[Font: Name=Microsoft Sans Serif, Size=8,25, Units=3, GdiCharSet=134, GdiVerticalFont=False]                    


Und das ohne string ergibt keinen Fehler mehr....klappt aber nicht.
Wie ist das eigentlich mit Apply`?`Wird das damit vielleicht i-wie intern gespeichert?

Alle Werte einzeln setzen waere auch problematisch bzw kostet viel arbeit, wie ich sehe.
Das ist ja nicht weiter wild, aber wozu , wenn es auch so gehen muesste?!

"Style" kann man auch nicht so einfach auslesen, d.h. am bsten boolische werte nehmen,
um einer konvertierung zu entkommen...

Mhm, oder muss das ganze doch in paint event??

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
TypeConverter converter = TypeDescriptor.GetConverter(typeof(Font));

                var xdocselect = xDocument.XPathSelectElements("Configuration");

                foreach (var Xselectel in xdocselect)
                {

                    Label_date.Font = (Font)converter.ConvertFromString(Xselectel.Element("Label_date_font").Value);
                }


danielf - Mi 09.06.10 08:11

Hallo,

also ich hab mir das nochmal angeschaut und mit TypConverter und Serializer geht es nicht. Es gibt immer noch die Möglichkeit es selbst zu Serialisieren. [http://msdn.microsoft.com/en-us/library/system.drawing.font%28VS.85%29.aspx]Hier[/url] ist Code wie man einen Wrapper macht. Ich würde allerdings eine eigne Klasse machen, die ISerializable implementiert.

Ich habe zwei Methode geschrieben mit denen die Font-Klasse serialisieren kannst. Kannst ja schauen was dir lieber ist.

Einmal die Extension:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
public static string Serialiase(this Font font)
{
    return string.Format("name={0};size={1};style={2}",
        font.FontFamily.Name,
        font.Size,
  font.Style);
}


Und ein Helper um daraus wieder ein Font-Objekt zu machen:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
public static Font CreateFont(string serialiasedFont)
{
    Dictionary<stringstring> values = Helper.TransformArguments(serialiasedFont);

    return new Font(
        values["name"],
        float.Parse(values["size"]),
        (FontStyle)Enum.Parse(typeof(FontStyle), values["style"]));
}

// mit
public static Dictionary<stringstring> TransformArguments(string args)
{
    Dictionary<stringstring> pairs = new Dictionary<stringstring>();
    MatchCollection matches = Regex.Matches(args, "(?<key>.+?)=(?<value>.+?)(;|$)");

    foreach (Match match in matches)
    {
        pairs.Add(
            match.Groups["key"].Value,
            match.Groups["value"].Value);
        }

    return pairs;
}


Viel Spaß & Gruß


Chiyoko - Mi 09.06.10 11:22

Danke dir,

ich probier damit mal ein wenig rum aber ich werd es erstmal beim einzelnen lassen.
Ganze Klassen kann ich sooderso noch nicht:D, aber ich ueb mich weiter :-)

C#-Quelltext
1:
2:
3:
4:
if (Convert.ToBoolean(Xselectel.Element("Label_time_font").Value) == true)
{
    Label_date.Font = new Font(Label_date.Font, FontStyle.Bold);
}


Chiyoko - Mi 09.06.10 12:40

So,...

nach langem hin und her hab ich jetzt doch eine Moeglichkeit gefunden, kurz und sauber Font zuzuweisen:)

Folgendes habe ich gemacht:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
// String variable festlegen
private string fontstring_date;

// beim auswaehlen des Fonts string zuweisen
if (sender == toolStripMenuItem_Font_date)
{
    FontDialog fontdiag2 = new FontDialog();
    
    if (fontdiag2.ShowDialog() == DialogResult.OK)
    {
        Label_date.Font = fontdiag2.Font;
        Font font = fontdiag2.Font;
        TypeConverter tc = TypeDescriptor.GetConverter(typeof(Font));
        fontstring_date = tc.ConvertToString(font);
    }
}


// nun das ganze in die Config schreiben lassen, hier nur das bsp font
XDocument docConfig = new XDocument(
     new XComment("UhrConfiguration"),
     new XElement("Configuration",
     new XElement("label_fontdate", fontstring_date)
     )
);
docConfig.Save(Path.Combine(Application.StartupPath, @"config.xml"), SaveOptions.None);


// und zu guter letzt auslesen:
private void config_einlesen()
{
    string configPfad = Path.Combine(Application.StartupPath, @"config.xml");
    if (File.Exists(configPfad))
    {
         XDocument xDocument = XDocument.Load(configPfad);

         var xdocselect = xDocument.XPathSelectElements("Configuration");
         TypeConverter tc = TypeDescriptor.GetConverter(typeof(Font));

         foreach (var Xselectel in xdocselect)
         {
              Font newFont (Font)tc.ConvertFromString(Xselectel.Element("label_fontdate").Value);
Label_date.Font = newFont;
         }
     }
}


Necaremus - Di 15.06.10 16:08

why not like this?


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
using System.ComponentModel;
public class FontToXml
    {
    Font font;
    public Font Font { get {return font;} set {font = value;} }

    private string FontToString(Font font)
    {
        TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(Font));
        return typeConverter.ConvertToString(font);
    }
    private Font StringToFont(string FontString)
    {
        TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(Font));
        return (Font)typeConverter.ConvertFromString(FontString);
    }
    public void Save()
    {
        var xFont = xmlSection.AddElement("FONT");
        xFontSQL.AddAttribute("VALUE", FontToString(font));
    }
    public void Load()
    {
        [...]
        switch (xElement.Name.ToString())
            {
                case "FONT":
                    font = StringToFont((string)xElement.Attribute("VALUE"));
                    break;
        [...]
    }
}


bei mir funktioniert's so oO

/edit:
das speichert er, und(!) ließt es richtig aus.

XML-Daten
1:
<Font VALUE="Courier New; 9pt" />                    

hab grad aber nicht getestet, ob er noch weitere angaben richtig ausließt (bold etc.)