是否有任何数据绑定允许之间的绑定框架(BCL或其他方式)的任何两个CLR性能实现INotifyPropertyChanged
和INotifyCollectionChanged
?似乎应该可以做这样的事情:
var binding = new Binding(); binding.Source = someSourceObject; binding.SourcePath = "Customer.Name"; binding.Target = someTargetObject; binding.TargetPath = "Client.Name"; BindingManager.Bind(binding);
在哪里someSourceObject
和someTargetObject
只是实施的POCO INotifyPropertyChanged
.但是,我没有意识到BCL对此有任何支持,并且不确定是否存在允许这样做的现有框架.
更新:鉴于没有现有的库,我已经自己写了自己的库.它可以在这里找到.
谢谢
我写了桁架填补空白.
我不知道有任何图书馆这样做 - 但你可以很容易地写自己的.
这是我在几分钟内敲定的基础,它建立了两个简单属性之间的双向数据绑定:
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);