如何在C#WPF中保存自定义类?
我正在开发一个WPF应用程序,我正在尝试在不参考Windows窗体的情况下完成它。我实际上使用的是WPF中完全开发的字体选择器和颜色选择器 我试图做的是让用户选择字体+颜色,并保存他们的选择,以便在应用程序的新启动时恢复它。字体存储在FontInfo类中:如何在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
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接口。现在看来很简单。非常感谢你的宝贵帮助。