问题
I have huge problem with saveing and restore ObservableCollection to IsolatedData. I'm trying with this code.
Helper class for Observable
public class ListItem {
public String Title { get; set; }
public bool Checked { get; set; }
public ListItem(String title, bool isChecked=false) {
Title = title;
Checked = isChecked;
}
private ListItem() { }
}
IsoHelper
public class IsoStoreHelper {
private static IsolatedStorageFile _isoStore;
public static IsolatedStorageFile IsoStore {
get { return _isoStore ?? (_isoStore = IsolatedStorageFile.GetUserStoreForApplication()); }
}
public static void SaveList<T>(string folderName, string dataName, ObservableCollection<T> dataList) where T : class {
if (!IsoStore.DirectoryExists(folderName)) {
IsoStore.CreateDirectory(folderName);
}
if (IsoStore.FileExists(folderName + "\\" + dataName+".dat")) {
IsoStore.DeleteFile(folderName + "\\" + dataName + ".dat");
}
string fileStreamName = string.Format("{0}\\{1}.dat", folderName, dataName);
try {
using (var stream = new IsolatedStorageFileStream(fileStreamName, FileMode.Create, IsoStore)) {
var dcs = new DataContractSerializer(typeof(ObservableCollection<T>));
dcs.WriteObject(stream, dataList);
}
} catch (Exception e) {
Debug.WriteLine(e.Message);
}
}
public static ObservableCollection<T> LoadList<T>(string folderName, string dataName) where T : class {
var retval = new ObservableCollection<T>();
if (!IsoStore.DirectoryExists(folderName) || !IsoStore.FileExists(folderName + "\\" + dataName + ".dat")) {
return retval;
}
string fileStreamName = string.Format("{0}\\{1}.dat", folderName, dataName);
var isf = IsoStore;
try {
var fileStream = IsoStore.OpenFile(fileStreamName, FileMode.OpenOrCreate);
if (fileStream.Length > 0) {
var dcs = new DataContractSerializer(typeof(ObservableCollection<T>));
retval = dcs.ReadObject(fileStream) as ObservableCollection<T>;
}
} catch {
retval = new ObservableCollection<T>();
}
return retval;
}
}
And I'm trying to use it this way
public partial class MainPage : PhoneApplicationPage{
public ObservableCollection<ListItem> ListItems = new ObservableCollection<ListItem>();
bool isListSaved;
private void Panorama_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) {
if (strTag.Equals("list") ) {
isListSave = false;
ListItems = IsoStoreHelper.LoadList<ListItem>("settings", "ListItems");
} else if (!isListSave) {
IsoStoreHelper.SaveList<ListItem>("settings", "ListItems", ListItems);
}
}
}
I keep getting A first chance exception of type 'System.Security.SecurityException' occurred in System.Runtime.Serialization.ni.dll
when I try read saved file at line ReadObject(fileStream)
but the FileAccess looks fine.
Any conclusion will be appreciated.
SOLVED:
Like Dmytro Tsiniavskyi said I totaly forgot about [DataContract] and [DataMember] in ListItem. Whats more I found better solution for saving and loading data. I end up with this code for ListItem
[DataContract]
public class ListItem {
[DataMember]
public String Title { get; set; }
[DataMember]
public bool Checked { get; set; }
public ListItem(String title, bool isChecked=false) {
Title = title;
Checked = isChecked;
}
private ListItem() { }
}
And this code for save/load collection which was originally founded here and modified a litte bit for better useage.
public partial class IsolatedRW {
public static void SaveData<T>(string fileName, T dataToSave) {
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
try {
if (store.FileExists(fileName)) {
store.DeleteFile(fileName);
}
if (!store.DirectoryExists("Settings")) store.CreateDirectory("Settings");
IsolatedStorageFileStream stream;
using (stream = store.OpenFile("Settings/"+fileName+".xml", System.IO.FileMode.Create, System.IO.FileAccess.Write)) {
var serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(stream, dataToSave);
}
stream.Close();
} catch (System.Security.SecurityException e) {
//MessageBox.Show(e.Message);
return;
}
Debug.WriteLine(store.FileExists("Settings/" + fileName + ".xml"));
}
}
public static T ReadData<T>(string fileName) {
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
Debug.WriteLine(store.FileExists("Settings/" + fileName + ".xml"));
if (store.FileExists("Settings/" + fileName + ".xml")) {
IsolatedStorageFileStream stream;
using (stream = store.OpenFile("Settings/"+fileName+".xml", FileMode.OpenOrCreate, FileAccess.Read)) {
try {
var serializer = new DataContractSerializer(typeof(T));
return (T)serializer.ReadObject(stream);
} catch (Exception) {
return default(T);
}
}
stream.Close();
}
return default(T);
}
}
}
回答1:
Try to add [DataContract]
attribute for your ListItem
class.
[DataContract]
public class ListItem {
[DataMember]
public String Title { get; set; }
[DataMember]
public bool Checked { get; set; }
public ListItem(String title, bool isChecked=false) {
Title = title;
Checked = isChecked;
}
private ListItem() { }
}
来源:https://stackoverflow.com/questions/19753106/write-restore-observablecollectiont