2014-09-25 57 views
1

DataTable saved to Session state loses event handlers類似,但其中推薦的解決方案不適用。我不會序列化會話數據。對象被保存在InProc中。對象在從會話中存儲/檢索後丟失事件處理程序

我有一個名爲Application與這些相關的位類:

public class Application { 
    public event PropertyChangedEventHandler PropertyChanged; 

    private Lazy<Asset> _asset; 

    public String AssetId { get; set; } 

    public Application() { 
     RestoreEventHandlers(new StreamingContext()); 
    } 

    [OnDeserialized] 
    public void RestoreEventHandlers(StreamingContext context) { 
     PropertyChanged += AssetId_PropertyChanged; 
     PropertyChanged.Invoke(this, new PropertyChangedEventArgs("AssetId")); 
    } 

    private void AssetId_PropertyChanged(Object sender, PropertyChangedEventArgs e) { 
     if (e.PropertyName == "AssetId") 
      _asset = new Lazy<Asset>(() => new Asset(AssetId)); 
    } 

    [NotifyPropertyChangedInvocator] 
    protected virtual void OnPropertyChanged([CallerMemberName] String propertyName = null) { 
     var handler = PropertyChanged; 
     if (handler != null) 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

的目標是_asset可重置每當相關AssetId屬性更改。我需要保持AssetIdAsset記錄的同步。我已經驗證了事件在第一次創建對象後調用。

應用程序創建,我把它放在會議這樣的後:

HttpContext.Current.Session["CurrentApplication"] = application; 

在後面的請求,我得到它從會議這樣的:

var application = HttpContext.Current.Session["CurrentApplication"] as Application; 

這正從一個叫這就是爲什麼我需要使用靜態對象來獲取當前請求上下文的幫助器類。

相同的方法後來我有一條線,這樣做,如果用戶要求改變應用程序上的資產:

application.AssetId = assetId; 

不調用事件處理這個任務之後。如果我這樣寫它,而不是它的工作原理像預期一樣:

application.RestoreEventHandlers(new StreamingContext()); 
application.AssetId = assetId; 

東西引起我的事件處理程序成爲綁定。有任何想法嗎?

+1

最後2個的代碼片段是一樣的,你的意思是把其他東西放在最後一個? – Rhumborl 2014-09-25 13:10:04

+0

@Rhumborl是的,趕上。對於那個很抱歉。我的意思是要表明,如果我沒有明確調用'RestoreEventHandlers',那麼事件不會觸發。我不想明確地調用它,因爲整個觀點是客戶端代碼很幸福地沒有意識到這種機制。 – Yuck 2014-09-25 13:15:39

回答

2

我可能會在這裏,但是PropertyChanged事件被調用,除了在RestoreEventHandlers()?我有它在,你需要手動提高它的屬性裏面的頭腦 - 見例如在http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx

private string _assetId; 

public string AssetId 
{ 
    get 
    { 
     return _assetId; 
    } 
    set 
    { 
     _assetId = value; 
     OnPropertyChanged(); 
    } 
} 

當然,你可以只重置_asset內的財產:

private string _assetId; 

public string AssetId 
{ 
    get 
    { 
     return _assetId; 
    } 
    set 
    { 
     _assetId = value; 
     _asset = new Lazy<Asset>(() => new Asset(AssetId)); 
    } 
} 
+0

你是對的 - 它根本沒有被調用。完美的解決方案,謝謝! – Yuck 2014-09-25 13:42:44

相關問題