[英]How can I implement a class that can be saved in User Settings?
我有以下課程-
[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
條目?”):我需要保留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
並將其文件名存儲在變量中,作為第一步,接下來我將嘗試同時對這兩個字符串進行相同操作)。
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>
SoundViewModel
需要反序列化的無參數構造函數。 僅公共屬性將被序列化。 您可以使用[XmlIgnore]
跳過屬性。
您也不能在用戶設置中保存通用類型(在您的情況下為Observable<T>
)。 雖然有一個簡單的解決方法,但我經常使用字典來解決。
[Serializable]
public class MySerializableCollection : List<SoundViewModel>{}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.