[英]INotifyPropertyChanged and Deserialization
鉴于:
public class MyClass : INotifyPropertyChanged
{
public List<string> _TestFire = new List<string>();
string _StringProp;
public string StringProp
{
get
{
return _StringProp;
}
set
{
if (_StringProp != value)
{
_StringProp = value;
RaisePropertyChanged("StringProp");
_TestFire.Add("fired " + DateTime.Now);
}
}
}
}
当您序列化然后反序列化此类时,它会触发RaisePropertyChanged
事件,这是不可取的。 是否可以防止在类反序列化时触发此事件?
var MyclassInstance = new MyClass() { StringProp = "None" };
MyclassInstance._TestFire.Clear(); // Clear property change history
var serobj = JsonConvert.SerializeObject();
var newitem = JsonConvert.DeserializeObject<MyClass>(serobj);
// newitem._TestFire.Count == 1, the set method was executed
如果类被反序列化,有没有办法获得bool
值? 那么我可以这样做:
set
{
if (_StringProp != value)
{
_StringProp = value;
if (!Deserializing)
{
RaisePropertyChanged("StringProp");
_TestFire.Add("fired " + DateTime.Now);
}
}
}
是的,您可以通过在您的类中实现OnDeserializing
和OnDeserialized
序列化回调方法来做您想做的事情。 在OnDeserializing
方法中,将您的私有_isDeserializing
变量设置为 true,并在OnDeserialized
中将其设置回 false。 我建议在RaisePropertyChanged
方法中进行_isDeserializing
检查,这样您就不会在每个属性中都有重复的代码。
所以你最终会得到这样的结果:
public class MyClass : INotifyPropertyChanged
{
public List<string> _TestFire = new List<string>();
string _StringProp;
public string StringProp
{
get
{
return _StringProp;
}
set
{
if (_StringProp != value)
{
_StringProp = value;
RaisePropertyChanged("StringProp");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
// don't raise the event if the property is being changed due to deserialization
if (_isDeserializing) return;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
_TestFire.Add(propertyName + " was fired " + DateTime.Now);
}
bool _isDeserializing = false;
[OnDeserializing]
internal void OnDeserializingMethod(StreamingContext context)
{
_isDeserializing = true;
}
[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context)
{
_isDeserializing = false;
}
}
工作演示: https : //dotnetfiddle.net/QkOcF4
你能解决这个问题的另一种方法是,以纪念你的公共属性[JsonIgnore]
然后标记与相应的支持字段[JsonProperty]
指定属性名称的JSON使用。 这将允许 Json.Net 直接设置支持字段,而不执行任何 mutator 逻辑。
public class MyClass : INotifyPropertyChanged
{
public List<string> _TestFire = new List<string>();
[JsonProperty("StringProp")]
string _StringProp;
[JsonIgnore]
public string StringProp
{
get
{
return _StringProp;
}
set
{
if (_StringProp != value)
{
_StringProp = value;
RaisePropertyChanged("StringProp");
_TestFire.Add("StringProp was fired " + DateTime.Now);
}
}
}
...
}
工作演示: https : //dotnetfiddle.net/jc7wDu
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.