与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
属性发生变化就会重置。我需要保持AssetId
和Asset
条记录同步。我已经验证在第一次创建对象后调用该事件。
创建应用程序后,我将它放在Session中,如下所示:
HttpContext.Current.Session["CurrentApplication"] = application;
在后续请求中,我从Session获取它:
var application = HttpContext.Current.Session["CurrentApplication"] as Application;
这是从辅助类调用的,这就是我需要使用静态对象来获取当前请求上下文的原因。
稍后在同一方法中,如果用户要求更改应用程序上的资产,我会有一行执行此操作:
application.AssetId = assetId;
在此赋值之后,不会调用事件处理程序。如果我这样写它而不是按预期工作:
application.RestoreEventHandlers(new StreamingContext());
application.AssetId = assetId;
导致我的事件处理程序无法绑定。有什么想法吗?
答案 0 :(得分: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));
}
}