数据绑定POCO属性

是否有任何数据绑定框架(BCL或其他)允许在实现INotifyPropertyChangedINotifyCollectionChanged 任何两个CLR属性之间进行绑定? 似乎应该可以做这样的事情:

 var binding = new Binding(); binding.Source = someSourceObject; binding.SourcePath = "Customer.Name"; binding.Target = someTargetObject; binding.TargetPath = "Client.Name"; BindingManager.Bind(binding); 

someSourceObjectsomeTargetObject只是实现INotifyPropertyChanged POCO。 但是,我不知道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); } }; } } 

当然,这段代码缺少一些细节。 要添加的内容包括

  • 检查是否已分配sourcetarget
  • 检查sourcePropertyNametargetPropertyName标识的属性targetPropertyName存在
  • 检查两个属性之间的类型兼容性

另外,Reflection相对较慢(虽然在丢弃之前对它进行基准测试,但速度并不慢),因此您可能希望使用编译表达式。

最后,鉴于按字符串指定属性容易出错,您可以使用Linq表达式和扩展方法。 然后而不是写作

 Binder.Bind( source, "Name", target, "Name") 

你可以写

 source.Bind( Name => target.Name); 

AutoMapper可以在两个实例之间复制值,但您必须编写自己的代码才能自动执行此操作。

也许Bindable LINQ或者连续的linq可以在这里提供帮助。 如果您尝试添加实际更新数据的实际“派生属性”的模型属性,以便UI更容易绑定,这两个框架应该有所帮助。

我写了一个小的Bind项目,完全支持neasted属性异步绑定操作之间的绑定。 sintax不能简单:

 //Two way binding between neasted properties: Bind.TwoWay(()=> client.Area.Data.Name == this.AreaName); //On change action execute: Bind .OnChange(()=> client.Personal.Name) .Do(x => clientName = x); 

如果您将属性定义为DependencyProperty ,则可以执行此操作。 WF和WPF都有它的实现(第一个链接用于WPF。对于WF就是这个 )所以你需要决定使用哪个 – 但两者都应该满足你的需求。