PropertyChanged:
public class MetaRecord : DomainObject
{
#region **属性成员
private MetaSample _试样1;
public MetaSample 试样1 {
get
{
return _试样1;
}
set{
_试样1=value;
this.RaisePropertyChanged(()=>试样1);
}
}
public MetaSample 试样2 { get; set; }
public MetaSample 试样3 { get; set; }
//可溶物含量计算的公式:A=(m2-m3)*100,保留1位小数。
private double _可溶物含量;
public double 可溶物含量
{
get
{
_可溶物含量 = Math.Round(( 试样1.可溶物含量 + 试样2.可溶物含量 + 试样3.可溶物含量 ) / 3, 1);
return _可溶物含量;
}
set
{
//_可溶物含量 = value;
_可溶物含量 = Math.Round(( 试样1.可溶物含量 + 试样2.可溶物含量 + 试样3.可溶物含量 ) / 3, 1);
this.RaisePropertyChanged(() => this.可溶物含量);
}
}
#endregion
#region **方法成员
public MetaRecord()
{
试样1 = new MetaSample();
试样2 = new MetaSample();
试样3 = new MetaSample();
//捕获内部对象的改变
试样1.PropertyChanged += new PropertyChangedEventHandler(value_PropertyChanged);
试样2.PropertyChanged += new PropertyChangedEventHandler(value_PropertyChanged);
试样3.PropertyChanged += new PropertyChangedEventHandler(value_PropertyChanged);
}
private void value_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
this.RaisePropertyChanged(() => this.可溶物含量);
}
#endregion
}
/// <summary>
/// 试样信息
/// </summary>
public class MetaSample : DomainObject
{
#region 属性成员
private double _萃取前重量;
public double 萃取前重量
{
get
{
return _萃取前重量;
}
set
{
if ( _萃取后重量 != 0 && value != 0 )
if ( _萃取后重量 > value )
{
throw new Exception("【萃取后重量M3】不能大于【萃取前的重量M2】!");
}
_萃取前重量 = value;
this.RaisePropertyChanged(() => this.可溶物含量);
this.RaisePropertyChanged(() => this.萃取前重量);
this.RaisePropertyChanged(() => this.萃取后重量);
}
}
private double _萃取后重量;
public double 萃取后重量
{
get
{
return _萃取后重量;
}
set
{
if ( value != 0 && _萃取前重量 != 0 )
if ( value > _萃取前重量 )
{
throw new Exception("【萃取后重量M3】不能大于【萃取前的重量M2】!");
}
_萃取后重量 = value;
this.RaisePropertyChanged(() => this.可溶物含量);
this.RaisePropertyChanged(() => this.萃取前重量);
this.RaisePropertyChanged(() => this.萃取后重量);
}
}
private double _可溶物含量;
public double 可溶物含量
{
get
{
//===============================================================
_可溶物含量 = Math.Round(( 萃取前重量 - 萃取后重量 ) * 100, 1);
return _可溶物含量;
}
set
{
_可溶物含量 = Math.Round(( 萃取前重量 - 萃取后重量 ) * 100, 1);
this.RaisePropertyChanged(() => this.可溶物含量);
}
}
#endregion
//===============
}
//================
//[OnDeserialized()]
//internal void OnDeserializedMethod(StreamingContext context)
//{
// 试样1.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(value_PropertyChanged);
// 试样2.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(value_PropertyChanged);
// 试样3.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(value_PropertyChanged);
//}
============================================================================
代码分析:
上述代码MetaRecord,通过反序列化,构建MetaSample,,但是反序列化又会重新构建MetaSample.
试样1.PropertyChanged += new PropertyChangedEventHandler(value_PropertyChanged);
试样2.PropertyChanged += new PropertyChangedEventHandler(value_PropertyChanged);
试样3.PropertyChanged += new PropertyChangedEventHandler(value_PropertyChanged);
这些代码可能失效。
结果属性通知失败。
C#的序列化,序列化MetaRecord的成员调用new MetaRecord(),事件PropertyChanged 被挂载,结果读取MetaSample的时候,对原来的PropertyChanged 进行清空,结果序列化就消失了。PropertyChanged =null,序列化失效了。
解决办法:
1)现在我自己开发序列化和序列化的工具,更重要的是避免序列化带来的版本异常问题。还有有时需要对只读对象进行强制序列化。
2)分析上述原理,你可以删除MetaSample的构造函数New MetaRecord(),建立一个非空的进行调用,避免反序列化调用此函数。或者将次方法不能做成Public不能外部调用,避免反序列化调用引起的其他属性丢失的问题。
3)试过调用反序列化的事件,反而繁琐了。因为是要处理MetaSample丢失PropertyChanged 的问题。麻烦了。
=====网络摘录-================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.IO;
using System.Xml;
namespace ReadDBLP
{
class ReadDBLP
{
public class MyResolver : XmlUrlResolver
{
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
{
if (absoluteUri.AbsoluteUri == "D:/people.dtd")
{
return File.Open("people.dtd", FileMode.Open);
}
return base.GetEntity(absoluteUri, role, ofObjectToReturn);
}
}
public void Load(string path)
{
XmlReaderSettings settings=new XmlReaderSettings();
settings.ValidationType = ValidationType.DTD;
settings.ProhibitDtd = false;
settings.XmlResolver = new MyResolver();
using (XmlReader reader = XmlReader.Create("D:/people.xml", settings))
{
XDocument document = XDocument.Load(reader);
}
}
}