再贴一个用在常用架构设计上的例子
可能有点难度,如果设计过类似的架构手法才会看明白。时间比较紧张,我就不解释了。
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class LinkToAttribute : Attribute
{
private string _myPropertyName;
//当前对象中用于与父类链接的对象属性
public string MyPropertyName
{
get { return _myPropertyName; }
set { _myPropertyName = value; }
}
private string _ParentPropertyName;
//父类对象中保存本对象链接的 ILIst 类型的属性
public string ParentPropertyName
{
get { return _ParentPropertyName; }
private set { _ParentPropertyName = value; }
}
public LinkToAttribute(string myProp, string parentProp)
{
this.MyPropertyName = myProp;
this.ParentPropertyName = parentProp;
}
/// <summary>
/// 自动维护与外部对象集合的链接关系。这里没有做检查,请确定属性存在,并且不要把属性和字段混淆。
/// </summary>
/// <param name="obj">被处理的对象</param>
/// <param name="isAdd">true-插入链接;false-删除链接</param>
public static void CascadeOnLink(object obj)
{
TypeDescriptor.GetAttributes(obj).OfType<LinkToAttribute>().ForEach(attr =>
{
var prop1 = TypeDescriptor.GetProperties(obj).Find(attr.MyPropertyName, false);
prop1.AddValueChanged(obj, new EventHandler(PropertyChanged));
});
}
static void PropertyChanged(object obj, EventArgs args)
{
var a = args as PropertyChangedEventArgsExt;
if (a != null)
{
var attr = TypeDescriptor.GetAttributes(obj).OfType<LinkToAttribute>()
.First(la => la.MyPropertyName == a.PropertyName);
if (a.OldValue != null)
{
IList array = (IList)TypeDescriptor.GetProperties(a.OldValue)
.Find(attr.ParentPropertyName, false).GetValue(obj);
if (array.Contains(obj))
array.Remove(obj);
}
var newValue = TypeDescriptor.GetProperties(obj)
.Find(a.PropertyName, false).GetValue(obj);
if (newValue != null)
{
IList array = (IList)TypeDescriptor.GetProperties(newValue)
.Find(attr.ParentPropertyName, false).GetValue(newValue);
if (!array.Contains(obj))
array.Add(obj);
}
}
}
}
public class PropertyChangedEventArgsExt : PropertyChangedEventArgs
{
private object _OldValue;
public object OldValue
{
get { return _OldValue; }
private set { _OldValue = value; }
}
public PropertyChangedEventArgsExt(string propertyName, object oldValue)
: base(propertyName)
{
this.OldValue = oldValue;
}
}
应用的例子:
public class TA
{
// ..............
private List<TB> _Tbs = new List<TB>();
public List<TB> Tbs
{
get { return _Tbs; }
}
}
[LinkTo("Ta", "Tbs")]
public class TB : INotifyPropertyChanged
{
//...................
private TA _ta;
public TA Ta
{
get { return _ta; }
set
{
var oldvalue = _ta;
_ta = value;
if (PropertyChanged != null) //通知任意监听INotifyPropertyChanged事件的客户端
PropertyChanged(this, new PropertyChangedEventArgsExt("Ta", oldvalue));
}
}
public TB()
{
LinkToAttribute.CascadeOnLink(this);
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}