我不知道有任何库可以做到这一点——但你可以很容易地编写自己的库。
这是我在几分钟内敲定的一个基础,它在两个简单属性之间建立了两种方式的数据绑定:
public static class Binder
{
public static void Bind(
INotifyPropertyChanged source,
string sourcePropertyName,
INotifyPropertyChanged target,
string targetPropertyName)
{
var sourceProperty
= source.GetType().GetProperty(sourcePropertyName);
var targetProperty
= target.GetType().GetProperty(targetPropertyName);
source.PropertyChanged +=
(s, a) =>
{
var sourceValue = sourceProperty.GetValue(source, null);
var targetValue = targetProperty.GetValue(target, null);
if (!Object.Equals(sourceValue, targetValue))
{
targetProperty.SetValue(target, sourceValue, null);
}
};
target.PropertyChanged +=
(s, a) =>
{
var sourceValue = sourceProperty.GetValue(source, null);
var targetValue = targetProperty.GetValue(target, null);
if (!Object.Equals(sourceValue, targetValue))
{
sourceProperty.SetValue(source, targetValue, null);
}
};
}
}
当然,这段代码缺少一些细节。要添加的内容包括
- 检查
source
并target
分配
- 检查由标识
sourcePropertyName
和targetPropertyName
存在的属性
- 检查两个属性之间的类型兼容性
此外,反射相对较慢(尽管在丢弃它之前对其进行基准测试,但它并没有那么慢),因此您可能希望使用已编译的表达式。
最后,鉴于通过字符串指定属性容易出错,您可以改用 Linq 表达式和扩展方法。然后代替写作
Binder.Bind( source, "Name", target, "Name")
你可以写
source.Bind( Name => target.Name);