Data Binding POCO Properties

主宰稳场 提交于 2019-11-28 17:45:38

问题


Are there any data binding frameworks (BCL or otherwise) that allow binding between any two CLR properties that implement INotifyPropertyChanged and INotifyCollectionChanged? It seems to be it should be possible to do something like this:

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

Where someSourceObject and someTargetObject are just POCOs that implement INotifyPropertyChanged. However, I am unaware of any BCL support for this, and am not sure if there are existing frameworks that permit this.

UPDATE: Given that there is no existing library available, I have taken it upon myself to write my own. It is available here.

Thanks


回答1:


I wrote Truss to fill the void.




回答2:


I'm not aware of any library that does this - but you could write your own fairly easily.

Here's a basis I knocked up in a few minutes that establishes two way data binding between two simple properties:

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);
                }
            };
    }
}

Of course, this code lacks a few niceties. Things to add include

  • Checking that source and target are assigned
  • Checking that the properties identified by sourcePropertyName and targetPropertyName exist
  • Checking for type compatibility between the two properties

Also, Reflection is relatively slow (though benchmark it before discarding it, it's not that slow), so you might want to use compiled expressions instead.

Lastly, given that specifying properties by string is error prone, you could use Linq expressions and extension methods instead. Then instead of writing

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

you could write

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



回答3:


AutoMapper can copy values between two instances, but you have to write your own code to make this happen automatically.




回答4:


Maybe Bindable LINQ or continuous linq can help here. If you're trying to add model properties that are actually "derived properties" of your actual, updating data, to make it easier for you UI to bind to, these two frameworks should help.




回答5:


I wrote an small Bind project with full support for binding between neasted properties async binding actions. The sintax can't be simpler:

//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);



回答6:


If you defined your properties as DependencyProperty's you could do it. Both WF and WPF have an implementation of it (first link is for WPF. For WF it is this one) so you need to decide which to use - but both should suffice for your needs.



来源:https://stackoverflow.com/questions/601880/data-binding-poco-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!