Any event handlers marked as [NonSerialized] get destroyed on deserialization, so you need to manually re-hook all the required event handlers to the deserialized object after deserialization [Binary]. The only problem is, I don't know how to do that. Any help?
My serializable class:
[Serializable]
public class DownloadEntry : INotifyPropertyChanged
{
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public string DownloadID { get; set; }
public Uri DownloadLink { get; set; }
public string FileName { get; set; }
private long size;
public long Size
{
get { return size; }
set
{
size = value;
OnPropertyChanged("Size");
}
}
public string SizePretty
{
get
{
return Helper.SizeSuffix(Size);
}
set
{
SizePretty = Size.ToString();
}
}
private string timeleft;
public string TimeLeft
{
get { return timeleft; }
set
{
timeleft = value;
OnPropertyChanged("TimeLeft");
}
}
private string status;
public string Status
{
get { return status; }
set
{
status = value;
OnPropertyChanged("Status");
}
}
private string transferrate;
public string TransferRate
{
get { return transferrate; }
set
{
transferrate = value;
OnPropertyChanged("TranferRate");
}
}
public DateTime DateAdded { get; set; }
public DateTime LastTryDate { get; set; }
public string SaveTo { get; set; }
public string Q { get; set; }
public string Description { get; set; }
public string AuthUsername { get; set; }
public string AuthPassword { get; set; }
public string ObtainedFrom { get; set; }
[NonSerialized]
private bool running;
public bool Running
{
get { return running; }
set
{
running = value;
OnPropertyChanged("Running");
}
}
}
Class where serialization and deserialization takes place:
public static class Downloads
{
public static ObservableCollection<DownloadEntry> DownloadEntries = new ObservableCollection<DownloadEntry>();
public static void Deserialize()
{
if (File.Exists("downloads.dat"))
{
IFormatter formatter = new BinaryFormatter();
using (FileStream stream = File.OpenRead("downloads.dat"))
{
DownloadEntries = (ObservableCollection<DownloadEntry>)formatter.Deserialize(stream);
}
}
}
public static void Serialize()
{
IFormatter formatter = new BinaryFormatter();
using (FileStream stream = File.Create("downloads.dat"))
{
formatter.Serialize(stream, DownloadEntries);
}
}
}
What I found on here, but there were no explanations on how to do it.
https://stackoverflow.com/a/6697942/4932305 :
most of my implementations of INotifyPropertyChanged I explicitly mark the PropertyChanged event as being non-serialized and then manually re-hook the event upon deserialization as appropriate.
Code present but it's in VB.net: Events not working with after Deserialization :
The problem is not that the Changed event isn't being fired; as long as the same class definition (with the setter that raises the event) is used for the deserialized object (with DataContract serialization that isn't a requisite), the event will be raised. What's happening is that the deserialized object no longer has the handler attached.
You cannot serialize or deserialize event handlers; at the very least, you shouldn't. Because they may point to references other than the current object reference, and because the deserialized object is a new reference in what is probably a different runtime, event handler references from the serialized object are useless on deserialization, because the reference will no longer point to the expected object in the new runtime's heap.