我有以下课程 -
[Serializable]
public class SoundViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
public string Name { get; private set; }
public SoundViewModel( string Name ) { this.Name = Name; }
private FileInfo
_RingIn = new FileInfo( "Sounds/RingIn.wav" ),
_Correct = new FileInfo( "Sounds/Correct.wav" ),
_Incorrect = new FileInfo( "Sounds/Incorrect.wav" ),
_TimeOver = new FileInfo( "Sounds/TimeOver.wav" );
public FileInfo RingIn {
get { return this._RingIn; }
set {
this._RingIn = value;
this.OnPropertyChanged( "RingIn" );
}
}
public FileInfo Correct {
get { return this._Correct; }
set {
this._Correct = value;
this.OnPropertyChanged( "Correct" );
}
}
public FileInfo Incorrect {
get { return this._Incorrect; }
set {
this._Incorrect = value;
this.OnPropertyChanged( "Incorrect" );
}
}
public FileInfo TimeOver {
get { return this._TimeOver; }
set {
this._TimeOver = value;
this.OnPropertyChanged( "TimeOver" );
}
}
private void OnPropertyChanged( string p ) {
if ( this.PropertyChanged != null )
this.PropertyChanged( this, new PropertyChangedEventArgs( p ) );
}
}
我需要将此类保存到应用程序的用户设置中,这就是原因(请不要说"为什么不在每个文件的用户设置中单独创建FileInfo
条目class?"):我需要保存这个类的51个单独的条目(一个单独表现为默认,另外50个;每个玩家一个,我 不 在设置中创建204个条目。
我快速搜索了如何创建一个可以序列化的类,以及我所说的MSDN文章
The easiest way to make a class serializable is to mark it with the Serializable attribute
显然,这不是可以通过“简单方式”完成的事情。
这是我在“用户设置”类中拥有的此条目的代码(以及这些条目的相应列表) -
XML -
<Setting Name="DefaultSounds" Type="EQLControls.Controls.SoundViewModel" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="PlayerSounds" Type="System.Collections.ObjectModel.ObservableCollection<EQLControls.Controls.SoundViewModel>" Scope="User">
<Value Profile="(Default)" />
</Setting>
C# -
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global::EQLControls.Controls.SoundViewModel DefaultSounds {
get {
return ((global::EQLControls.Controls.SoundViewModel)(this["DefaultSounds"]));
}
set {
this["DefaultSounds"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global::System.Collections.ObjectModel.ObservableCollection<EQLControls.Controls.SoundViewModel> PlayerSounds {
get {
return ((global::System.Collections.ObjectModel.ObservableCollection<EQLControls.Controls.SoundViewModel>)(this["PlayerSounds"]));
}
set {
this["PlayerSounds"] = value;
}
}
如有必要,我可以提供更多详细信息。
如何实现SoundViewModel类,以便在调用Settings.Default.Save()
时,设置将被保存?
另外 - 我发现的一条线索是,当我尝试保存时,这就是我在用户设置文件中得到的内容:
<EQLControls.Properties.Settings>
<setting name="DefaultSounds" serializeAs="Xml">
<value />
</setting>
<setting name="PlayerSounds" serializeAs="Xml">
<value />
</setting>
</EQLControls.Properties.Settings>
有人建议我使用文件名而不是FileInfo
对象。
我尝试了这个,但它没有用 - (我将属性保留为FileInfo
并将它们的文件名存储在变量中,作为第一个镜头,我接下来会尝试对两个作为字符串执行相同操作。)< / p>
public class SoundViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
public string Name { get; private set; }
public SoundViewModel( string Name ) { this.Name = Name; }
private string
_RingIn = "Sounds/RingIn.wav",
_Correct = "Sounds/Correct.wav",
_Incorrect = "Sounds/Incorrect.wav",
_TimeOver = "Sounds/TimeOver.wav";
public FileInfo RingIn {
get { return new FileInfo(this._RingIn ?? "Sounds/RingIn.wav"); }
set {
this._RingIn = value.FullName;
this.OnPropertyChanged( "RingIn" );
}
}
public FileInfo Correct {
get { return new FileInfo(this._Correct ?? "Sounds/Correct.wav"); }
set {
this._Correct = value.FullName;
this.OnPropertyChanged( "Correct" );
}
}
public FileInfo Incorrect {
get { return new FileInfo(this._Incorrect ?? "Sounds/Incorrect.wav"); }
set {
this._Incorrect = value.FullName;
this.OnPropertyChanged( "Incorrect" );
}
}
public FileInfo TimeOver {
get { return new FileInfo(this._TimeOver ?? "Sounds/TimeOver.wav"); }
set {
this._TimeOver = value.FullName;
this.OnPropertyChanged( "TimeOver" );
}
}
private void OnPropertyChanged( string p ) {
if ( this.PropertyChanged != null )
this.PropertyChanged( this, new PropertyChangedEventArgs( p ) );
}
}
我删除了FileInfo属性并替换为字符串:
public class SoundViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
public string Name { get; private set; }
public SoundViewModel( string Name ) { this.Name = Name; }
private string
_RingIn = "Sounds/RingIn.wav",
_Correct = "Sounds/Correct.wav",
_Incorrect = "Sounds/Incorrect.wav",
_TimeOver = "Sounds/TimeOver.wav";
public string RingIn {
get { return this._RingIn; }
set {
this._RingIn = value;
this.OnPropertyChanged( "RingIn" );
}
}
public string Correct {
get { return this._Correct; }
set {
this._Correct = value;
this.OnPropertyChanged( "Correct" );
}
}
public string Incorrect {
get { return this._Incorrect; }
set {
this._Incorrect = value;
this.OnPropertyChanged( "Incorrect" );
}
}
public string TimeOver {
get { return this._TimeOver; }
set {
this._TimeOver = value;
this.OnPropertyChanged( "TimeOver" );
}
}
private void OnPropertyChanged( string p ) {
if ( this.PropertyChanged != null )
this.PropertyChanged( this, new PropertyChangedEventArgs( p ) );
}
}
仍然没有爱,保存的user.config文件是荒芜的。
<EQLControls.Properties.Settings>
<setting name="PlayerSounds" serializeAs="Xml">
<value />
</setting>
</EQLControls.Properties.Settings>
答案 0 :(得分:1)
SoundViewModel
需要一个无参数构造函数来进行反序列化。仅序列化公共属性。您可以使用[XmlIgnore]
跳过属性。
您也无法在用户设置中保存通用类型(在您的情况下为Observable<T>
)。虽然有一个简单的解决方法,但我经常用词典来做这件事。
[Serializable]
public class MySerializableCollection : List<SoundViewModel>{}