簡體   English   中英

如何手動將非序列化的INotifyPropertyChanged事件處理程序重新掛鈎到反序列化的對象

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM