17

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

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

实施. someSourceObject_ someTargetObject_ INotifyPropertyChanged但是,我不知道对此有任何 BCL 支持,并且不确定是否存在允许这样做的现有框架。

更新:鉴于没有可用的现有库,我自己编写了自己的库。它可以在这里找到

谢谢

4

6 回答 6

11

我写了桁架来填补空白。

于 2009-06-11T12:16:02.033 回答
8

我不知道有任何可以做到这一点——但你可以很容易地编写自己的库。

这是我在几分钟内敲定的一个基础,它在两个简单属性之间建立了两种方式的数据绑定:

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存在的属性
  • 检查两个属性之间的类型兼容性

此外,反射相对较慢(尽管在丢弃它之前对其进行基准测试,但它并没有那么慢),因此您可能希望使用已编译的表达式。

最后,鉴于通过字符串指定属性容易出错,您可以改用 Linq 表达式和扩展方法。然后代替写作

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

你可以写

source.Bind( Name => target.Name);
于 2009-03-10T06:35:59.847 回答
1

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

于 2009-03-06T00:42:00.480 回答
1

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

于 2009-03-06T10:16:00.273 回答
0

我编写了一个小型Bind项目,它完全支持嵌套属性异步绑定操作之间的绑定。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);
于 2016-11-16T16:51:26.497 回答
-2

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

于 2009-03-11T11:35:47.777 回答