如何在C#WPF中保存自定义类?

如何在C#WPF中保存自定义类?,c#,wpf,class,save,settings,C#,Wpf,Class,Save,Settings,我正在开发一个WPF应用程序,我正在尝试在不参考Windows窗体的情况下完成它。我实际上使用的是WPF中完全开发的字体选择器和颜色选择器 我试图做的是让用户选择字体+颜色,并保存他们的选择,以便在应用程序的新启动时恢复它。字体存储在FontInfo类中: public class FontInfo { public SolidColorBrush BrushColor { get; set; } public FontColor Color { get { return Ava

我正在开发一个WPF应用程序,我正在尝试在不参考Windows窗体的情况下完成它。我实际上使用的是WPF中完全开发的字体选择器和颜色选择器

我试图做的是让用户选择字体+颜色,并保存他们的选择,以便在应用程序的新启动时恢复它。字体存储在FontInfo类中:

public class FontInfo
{
    public SolidColorBrush BrushColor { get; set; }
    public FontColor Color { get { return AvailableColors.GetFontColor(this.BrushColor); } }
    public FontFamily Family { get; set; }
    public double Size { get; set; }
    public FontStretch Stretch { get; set; }
    public FontStyle Style { get; set; }
    public FontWeight Weight { get; set; }

    public FamilyTypeface Typeface
    {
        get
        {
            FamilyTypeface ftf = new FamilyTypeface()
            {
                Stretch = this.Stretch,
                Weight = this.Weight,
                Style = this.Style
            };
            return ftf;
        }
    }

    public FontInfo() { }

    public FontInfo(FontFamily fam, double sz, FontStyle style, FontStretch strc, FontWeight weight, SolidColorBrush c)
    {
        this.Family = fam;
        this.Size = sz;
        this.Style = style;
        this.Stretch = strc;
        this.Weight = weight;
        this.BrushColor = c;
    }

    public static void ApplyFont(Control control, FontInfo font)
    {
        control.FontFamily = font.Family;
        control.FontSize = font.Size;
        control.FontStyle = font.Style;
        control.FontStretch = font.Stretch;
        control.FontWeight = font.Weight;
        control.Foreground = font.BrushColor;
    }

    public static FontInfo GetControlFont(Control control)
    {
        FontInfo font = new FontInfo()
        {
            Family = control.FontFamily,
            Size = control.FontSize,
            Style = control.FontStyle,
            Stretch = control.FontStretch,
            Weight = control.FontWeight,
            BrushColor = (SolidColorBrush)control.Foreground
        };
        return font;
    }

    public static string TypefaceToString(FamilyTypeface ttf)
    {
        StringBuilder sb = new StringBuilder(ttf.Stretch.ToString());
        sb.Append("-");
        sb.Append(ttf.Weight.ToString());
        sb.Append("-");
        sb.Append(ttf.Style.ToString());
        return sb.ToString();
    }
}
我不明白什么是最好的选择。我看到它可以通过XML序列化实现,但我失败了,我看到每个示例都使用带有字符串和int变量的简单类


冷,请给我指一些文档或给我一个如何做的示例?

您在序列化方面走的是正确的,但有时可能会很棘手。这里有一个简单的例子,你可以在你的课堂上尝试,这应该是有效的。这利用了二进制序列化

您必须始终做的第一件事是使用如下属性使类可序列化

[Serializable] //Add this attribute above your class
public class FontInfo
{
   //...
}
接下来,尝试这个简单的示例,看看您的类是否序列化、保存到文件,然后反序列化

using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

public void Example()
{
     FontInfo fi = new FontInfo(){Size = 12};

     BinaryFormatter bf = new BinaryFormatter();

     // Serialize the Binary Object and save to file
     using (FileStream fsout = new FileStream("FontInfo.txt", FileMode.Create, FileAccess.Write, FileShare.None))
     {
            bf.Serialize(fsout, fi);
     }

     //Open saved file and deserialize
     using (FileStream fsin = new FileStream("FontInfo.txt", FileMode.Open, FileAccess.Read, FileShare.None))
     {
         FontInfo fi2 = (FontInfo)bf.Deserialize(fsin);
         Console.WriteLine(fi2.Size); //Should output 12

     }
}


这只是一个简单的例子,但应该从正确的方向开始。

因为像
SolidColorBrush
这样的类型没有使用
SerializableAttribute
修饰,默认情况下它们不会序列化。因此,您必须通过实现
ISerializable
接口并将这些类型转换为可序列化格式(例如,
string
)来手动完成这项工作。这可以通过使用几乎所有这些类型的内置库转换器来实现

[Serializable]
public class FontInfo : ISerializable
{
  public FontInfo()
  {
    // Empty constructor required to compile.
  }

  public SolidColorBrush BrushColor { get; set; }
  //public FontColor Color { get { return AvailableColors.GetFontColor(this.BrushColor); } }
  public FontFamily Family { get; set; }
  public double Size { get; set; }
  public FontStretch Stretch { get; set; }
  public FontStyle Style { get; set; }
  public FontWeight Weight { get; set; }

  public FamilyTypeface Typeface => 
    new FamilyTypeface()
    {
      Stretch = this.Stretch,
      Weight = this.Weight,
      Style = this.Style
    };


  // Implement this method to serialize data. The method is called 
  // on serialization e.g., by the BinaryFormatter.
  public void GetObjectData(SerializationInfo info, StreamingContext context)
  {
    // Use the AddValue method to specify serialized values.
    info.AddValue(nameof(this.BrushColor), new ColorConverter().ConvertToString(this.BrushColor.Color), typeof(string));
    info.AddValue(nameof(this.Family), new FontFamilyConverter().ConvertToString(this.Family), typeof(string));
    info.AddValue(nameof(this.Stretch), new FontStretchConverter().ConvertToString(this.Stretch), typeof(string));
    info.AddValue(nameof(this.Style), new FontStyleConverter().ConvertToString(this.Style), typeof(string));
    info.AddValue(nameof(this.Weight), new FontWeightConverter().ConvertToString(this.Weight), typeof(string));
    info.AddValue(nameof(this.Size), this.Size, typeof(double));
  }


  // The special constructor is used 
  // e.g. by the BinaryFormatter to deserialize values.
  public FontInfo(SerializationInfo info, StreamingContext context)
  {
    // Reset the property value using the GetValue method.
    this.BrushColor = new SolidColorBrush((Color) ColorConverter.ConvertFromString((string)info.GetValue(nameof(this.BrushColor), typeof(string))));
    this.Family = (FontFamily) new FontFamilyConverter().ConvertFromString((string)info.GetValue(nameof(this.Family), typeof(string)));
    this.Stretch = (FontStretch) new FontStretchConverter().ConvertFromString((string)info.GetValue(nameof(this.Stretch), typeof(string)));
    this.Style = (FontStyle) new FontStyleConverter().ConvertFromString((string)info.GetValue(nameof(this.Style), typeof(string)));
    this.Weight = (FontWeight) new FontWeightConverter().ConvertFromString((string)info.GetValue(nameof(this.Weight), typeof(string)));
    this.Size = (double) info.GetValue(nameof(this.Size), typeof(double));
  }
}
用法

public static void SerializeItem(string fileName)
{
  var fontInfo = new FontInfo();

  using (FileStream fileStream  = File.Create(fileName))
  {
    var formatter = new BinaryFormatter();
    formatter.Serialize(fileStream, fontInfo);
  }
}

public static void DeserializeItem(string fileName)
{     
  using (FileStream fileStream  = File.OpenRead(fileName))
  {
    var formatter = new BinaryFormatter();
    FontInfo fontInfo = (FontInfo) formatter.Deserialize(fileStream);
  }       
}       
注 我不知道什么是
FontColor
必须是您的自定义类型。在这种情况下,您还需要使用
SerializableAttribute
对其进行修饰,以便对其进行序列化(或提供转换器)


我没有测试代码。将此作为如何通过实现来序列化的指南。

Binary:.XML:,@BionicCode非常感谢您的回答。我正在阅读这些文件,但根据Tronald的回答,我有同样的问题。如果我尝试序列化我的类,我会收到一个错误,因为我无法序列化其中的对象。我添加了一个答案,以说明如何通过实现
ISerializable
来解决这个问题。非常感谢您的回答。我尝试了您的解决方案,但出现了一个错误,因为FontInfo中使用的其他类(例如SolidColorBrush)在其命名空间中不可序列化。我该怎么得到这个?我对这东西还不熟悉。非常感谢你的帮助。你好@BionicCode。你的代码工作得很好!我不知道如何利用ISerializable接口。现在看来很简单。非常感谢你的宝贵帮助。