[英]How to manually re-hook a non-serialized INotifyPropertyChanged event handler to the deserialized object
在反序列化過程中,任何標記為[NonSerialized]的事件處理程序都會被銷毀,因此您需要在反序列化[Binary]之后手動將所有必需的事件處理程序重新掛鈎到反序列化的對象。 唯一的問題是,我不知道該怎么做。 有什么幫助嗎?
我的可序列化類:
[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");
}
}
}
進行序列化和反序列化的類:
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);
}
}
}
我在這里找到了什么,但是沒有關於如何執行的解釋。
https://stackoverflow.com/a/6697942/4932305 :
我的INotifyPropertyChanged的大多數實現都將PropertyChanged事件明確標記為未序列化,然后在反序列化后適當地手動重新掛鈎該事件。
代碼存在,但在VB.net中: 反序列化后事件無法使用 :
問題不在於未觸發Changed事件。 只要將相同的類定義(帶有引發事件的setter)用於反序列化的對象(不需要使用DataContract序列化),就會引發該事件。 發生的事情是,反序列化的對象不再具有附加的處理程序。
您不能序列化或反序列化事件處理程序; 至少,您不應該這樣做。 因為它們可能指向當前對象引用以外的引用,並且由於反序列化的對象是新的引用(可能與運行時不同),所以序列化對象的事件處理程序引用在反序列化時無用,因為該引用將不再指向新運行時堆中的預期對象。
您必須使用序列化的內容(xml或二進制)來實現靜態類以對其進行反序列化,並訂閱所需的事件。
public static DownloadEntry Deserialize(string serializedXmlContents)
{
DownloadEntry downloadEntry= ... // Do the deserialization
// Subscribe to your events
return downloadEntry;
}
解決方案在這里: http : //web.archive.org/web/20150531190503/http : //www.gavaghan.org/blog/2007/07/20/demonstrating-bindinglist-serialization-bug/
因為我無法將其應用於我的ObservableCollection。 我只是使用了BindingList,其作用與ObservableCollection幾乎相同。 我要做的就是將CollectionChanged事件更改為ListChanged,問題解決了。
我已經花了幾天時間沉迷於此。 幸運的是,現在結束了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.