62,074
社区成员
发帖
与我相关
我的任务
分享
public class AspDotNetBinding
{
public enum Direction
{
Oneway,
Twoway
}
private bool pageLoaded = false;
private bool targetChanged = false;
//当Source的某个属性变动时,自动将值传递给Target的某个属性,或者相反。通常,Soruce是一个asp.net的控件,而Target是一个内存中的数据模型对象。
public AspDotNetBinding(Control source, string sourcePropName, Object target, string targetPropName,
Func<object, object> parse, Func<object, object> format, Direction dir)
{
source.Page.Load += new EventHandler((s, e) => this.pageLoaded = true);
var sp = TypeDescriptor.GetProperties(source).Find(sourcePropName, false);
var tp = TypeDescriptor.GetProperties(target).Find(targetPropName, false); //有时需要在页面内刷新后台数据并回调前台。
if (!sp.IsReadOnly)
source.Page.PreRender += new EventHandler((s, e) =>
{
if (!source.Page.IsPostBack || targetChanged)
{
var sv = sp.GetValue(source);
var tv = tp.GetValue(target);
if (format != null)
tv = format(tv);
if (!sv.Equals(tv))
sp.SetValue(source, tv);
}
});
if (dir != Direction.Oneway && !tp.IsReadOnly)
sp.AddValueChanged(source, (s, e) =>
{
if (this.pageLoaded) //确保只有被asp.net机制的 IPostDataChangedEvent 触发的修改才更新后台数据。
{
var sv = sp.GetValue(source);
var tv = tp.GetValue(target);
if (parse != null)
sv = parse(sv);
if (!sv.Equals(tv))
tp.SetValue(target, sv);
}
});
tp.AddValueChanged(target, (s, e) =>
{
targetChanged = true;
});
}
//当asp.net的控件Source的某个事件触发,将自动改变另外一个对象Target的某个属性。
public AspDotNetBinding(Control source, string eventName, Func<object> getValue, Object target, string targetPropName)
{
var tp = TypeDescriptor.GetProperties(target).Find(targetPropName, false);
if (!tp.IsReadOnly)
TypeDescriptor.GetEvents(source).Find(eventName, false)
.AddEventHandler(source, new EventHandler((s, e) =>
{
var tv = tp.GetValue(target);
var value = getValue();
if (!value.Equals(tv))
tp.SetValue(target, value);
}));
}
}