WPF: Model to View Model data binding to implement Two Step View I am trying to use Two Step View pattern in WPF. The problem is about keeping things in sync – I need a way to data-bind models to view models. Are there any good existing solutions? My approach is to introduce Property&lt;T&gt; to be used this way:

public abstract class TextField : ObservableObject
{
    public Property&lt;bool&gt; IsEnabled { get; set; } = true;
    public Property&lt;string&gt; Text { get; set; } = false;
    // etc.
}


Where property supports databinding updates:

public class Property&lt;T&gt; : ObservableObject
{
    public static implicit operator Property&lt;T&gt;(T value) =&gt; new Property&lt;T&gt;(() =&gt; value);
    public static implicit operator T(Property&lt;T&gt; property) =&gt; property.Value;

    public Property(Func&lt;T&gt; getter, params INotifyPropertyChanged[] dataSources)
        : this(getter, v =&gt; { throw new NotSupportedException(); }, dataSources)
    {            
    }

    public Property(Func&lt;T&gt; getter, Action&lt;T&gt; setter, params INotifyPropertyChanged[] dataSources)
    {
        Getter = getter;
        Setter = setter;
        foreach (var dataSource in dataSources)
            dataSource.PropertyChanged += (s, e) =&gt; RaisePropertyChanged("Value");
    }

    public T Value
    {
        get { return Getter(); }
        set { Setter(value); }
    }

    Func&lt;T&gt; Getter { get; }
    Action&lt;T&gt; Setter { get; }
}


I use helper method Bind in the following way for view model construction:

        var model = new DocumentModel();
        var viewModel = new TextField 
        { 
           Text = model.Bind(m =&gt; m.FullName), 
           IsEnabled = model.Bind(m =&gt; m.FullName != "") 
        };


Where bind defined as:

public static class Binding
{
    public static Property&lt;TTarget&gt; Bind&lt;TSource, TTarget&gt;(this TSource source, Expression&lt;Func&lt;TSource, TTarget&gt;&gt; mapper)
        where TSource : INotifyPropertyChanged
    {
        Mapping&lt;TSource, TTarget&gt; mapping = mapper;
        return new Property&lt;TTarget&gt;(() =&gt; mapping[source], v =&gt; mapping[source] = v, source);
    }
}


Where Mapping compiles getter and setter from the expression:

class Mapping&lt;TSource, TTarget&gt;
{
    public static implicit operator Mapping&lt;TSource, TTarget&gt;(Expression&lt;Func&lt;TSource, TTarget&gt;&gt; mapping) =&gt;
        new Mapping&lt;TSource, TTarget&gt;(mapping);

    [DebuggerHidden]
    public Mapping(Expression&lt;Func&lt;TSource, TTarget&gt;&gt; mapper)
    {
        Field = mapper.Parameters[0].Name;
        Getter = mapper.Compile().Invoke;

        try
        {
            var newValue = Expression.Parameter(mapper.Body.Type);
            var assign = Expression.Lambda&lt;Action&lt;TSource, TTarget&gt;&gt;(
                Expression.Assign(mapper.Body, newValue),
                mapper.Parameters[0], newValue);

            Setter = assign.Compile().Invoke;
        }
        catch(ArgumentException)
        {
        }
    }

    public string Field { get; }

    public TTarget this[TSource source]
    {
        get { return Getter(source); }
        set { Setter(source, value); }
    }

    Func&lt;TSource, TTarget&gt; Getter { get; }
    Action&lt;TSource, TTarget&gt; Setter { get; }
}


It works somehow:

 &lt;DataTemplate DataType="{x:Type f:TextField}"&gt;
    &lt;TextBox 
        Text="{Binding Path=Text.Value, UpdateSourceTrigger=PropertyChanged}"
        IsEnabled="{Binding Path=IsEnabled.Value}"/&gt;
 &lt;/DataTemplate&gt;


Does it look ugly? Two Step View helps me a lot…
Here is how I redefined it now. Demo:

public MainWindow()
{
    InitializeComponent();

    var dvm = new DemoViewModel();
    var dm = new DemoModel();
    dvm.Text = dm.Select(m =&gt; m.Text); // bidirectional
    dvm.Text2 = dm.Select(m =&gt; m.Text); // bidirectional
    dvm.IsReadOnly = dm.Select(m =&gt; m.Text.Length &gt; 4); // calculable
    DataContext = dvm;
}


Where:

class DemoModel : Model
{
    string _text = "";

    public string Text
    {
        get { return _text; }
        set { Set(() =&gt; Text, ref _text, value); }
    }
}


And (too verbose, but it is a stupid WPF thing):

class DemoViewModel : ViewModel
{
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(DemoViewModel));

    public static readonly DependencyProperty Text2Property =
        DependencyProperty.Register("Text2", typeof(string), typeof(DemoViewModel));

    public static readonly DependencyProperty IsReadOnlyProperty =
        DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(DemoViewModel));

    public Binding&lt;string&gt; Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetBinding(TextProperty, value); }
    }

    public Binding&lt;string&gt; Text2
    {
        get { return (string)GetValue(Text2Property); }
        set { SetBinding(Text2Property, value); }
    }

    public Binding&lt;bool&gt; IsReadOnly
    {
        get { return (bool)GetValue(IsReadOnlyProperty); }
        set { SetBinding(IsReadOnlyProperty, value); }
    }
}


Library classes:

class Model : ObservableObject
{
}


And:

Outdated - see below:

class ViewModel : FrameworkElement
{
    protected BindingExpressionBase SetBinding&lt;T&gt;
        (DependencyProperty dp, Binding&lt;T&gt; property)
    {
        var binding = new Binding("Value") 
            { Source = property, Mode = BindingMode.TwoWay };

        return SetBinding(dp, binding);
    }
}


Now

public class ViewModel : DependencyObject
{
    protected BindingExpressionBase SetBinding&lt;T&gt;(DependencyProperty dp, Binding&lt;T&gt; property)
    {
        var binding = new Binding("Value")
        {
            Source = property,
            Mode = BindingMode.TwoWay
        };

        return BindingOperations.SetBinding(this, dp, binding);
    }
}


And:

public static class ModelBinding
{
    public static Binding&lt;T&gt; Select&lt;TM, T&gt;(this TM m, Expression&lt;Func&lt;TM, T&gt;&gt; mapper)
    {
        Mapping&lt;TM, T&gt; mapping = mapper;
        return new Binding&lt;T&gt;(() =&gt; mapping[m], v =&gt; mapping[m] = v, m);
    }
}


And:

public class Binding&lt;T&gt; : ObservableObject
{
    public static implicit operator Binding&lt;T&gt;(T value) =&gt; new Binding&lt;T&gt;(() =&gt; value);        
    public static implicit operator T(Binding&lt;T&gt; property) =&gt; property.Value;

    public Binding(Func&lt;T&gt; getter, params object[] dataSources)
        : this(getter, v =&gt; { throw new NotSupportedException(); }, dataSources)
    {
    }

    public Binding(Func&lt;T&gt; getter, Action&lt;T&gt; setter, params object[] dataSources)
    {
        Getter = getter;
        Setter = setter;            
        foreach (var npc in dataSources.OfType&lt;INotifyPropertyChanged&gt;())
            npc.PropertyChanged += (s, e) =&gt; RaisePropertyChanged("Value");
    }

    public T Value
    {
        get { return Getter(); }
        set { Setter(value); }
    }

    Func&lt;T&gt; Getter { get; }
    Action&lt;T&gt; Setter { get; }
}


And:

class Mapping&lt;TSource, TTarget&gt;
{
    public static implicit operator Mapping&lt;TSource, TTarget&gt;(Expression&lt;Func&lt;TSource, TTarget&gt;&gt; mapping) =&gt;
        new Mapping&lt;TSource, TTarget&gt;(mapping);

    [DebuggerHidden]
    public Mapping(Expression&lt;Func&lt;TSource, TTarget&gt;&gt; mapper)
    {
        Getter = mapper.Compile().Invoke;

        try
        {
            var newValue = System.Linq.Expressions.Expression.Parameter(mapper.Body.Type);
            var assign = System.Linq.Expressions.Expression.Lambda&lt;Action&lt;TSource, TTarget&gt;&gt;(
                System.Linq.Expressions.Expression.Assign(mapper.Body, newValue),
                mapper.Parameters[0], newValue);

            Setter = assign.Compile().Invoke;
        }
        catch (ArgumentException)
        {
        }
    }

    public TTarget this[TSource source]
    {
        get { return Getter(source); }
        set { Setter(source, value); }
    }

    Func&lt;TSource, TTarget&gt; Getter { get; }
    Action&lt;TSource, TTarget&gt; Setter { get; }
}