Skip to content

Instantly share code, notes, and snippets.

@thongdoan
Last active August 9, 2016 10:14
Show Gist options
  • Save thongdoan/ce1e3255d423c2fd829a135980c23cf3 to your computer and use it in GitHub Desktop.
Save thongdoan/ce1e3255d423c2fd829a135980c23cf3 to your computer and use it in GitHub Desktop.
Xamarin Form Fluent Binding
namespace Examples
{
public class LoginView
{
private Entry _txtUserName;
private Entry _txtPassword;
private Button _btnLogin;
public LoginView ()
{
var set = this.CreateBindingSet<LoginViewModel> ();
set.Bind (_txtUserName).For (t => t.Text).To (vm => vm.UserName);
set.Bind (_txtPassword).For (t => t.Text).To (vm => vm.Password);
set.Bind (_btnLogin).For (b => b.Command).To (vm => vm.LoginCommand);
/*Or
set.Bind (_txtUserName).For (Entry.TextProperty).To (vm => vm.UserName);
set.Bind (_txtPassword).For (Entry.TextProperty).To (vm => vm.Password);
set.Bind (_btnLogin).For (Button.CommandProperty).To (vm => vm.LoginCommand);
*/
set.Apply ();
}
}
}
using System;
namespace XForm
{
public interface IXAppliable
{
void Apply ();
}
}
using System;
using System.Linq.Expressions;
using Xamarin.Forms;
using System.Reflection;
using System.Linq;
using System.Diagnostics;
namespace XForm
{
public class XFluentBindingDescription<TTarget, TSource> : IXAppliable where TTarget : BindableObject
{
private readonly TTarget _self;
private BindableProperty _targetProperty;
private Expression<Func<TSource, object>> _sourceProperty;
private BindingMode _mode;
private IValueConverter _converter;
private object _converterParameter;
private string _stringFormat;
public XFluentBindingDescription (TTarget self)
{
if (self == null)
throw new ArgumentNullException (nameof (self));
_self = self;
_mode = BindingMode.Default;
}
public XFluentBindingDescription<TTarget, TSource> For (BindableProperty targetProperty)
{
_targetProperty = targetProperty;
return this;
}
public XFluentBindingDescription<TTarget, TSource> For (Expression<Func<TTarget, object>> targetPropertyPath)
{
string targetPropertyName = (targetPropertyPath.Body as MemberExpression).Member.Name + "Property";
return For (targetPropertyName);
}
public XFluentBindingDescription<TTarget, TSource> For (string targetPropertyName)
{
FieldInfo fieldInfo = null;
Type type = _self.GetType ();
do {
fieldInfo = type.GetRuntimeField (targetPropertyName);
if (fieldInfo != null)
break;
type = type.GetTypeInfo ()?.BaseType;
}
while (type != null);
if (fieldInfo == null)
throw new InvalidOperationException ("Not found BindableProperty: " + targetPropertyName);
_targetProperty = (Xamarin.Forms.BindableProperty)fieldInfo.GetValue (null);
return this;
}
public XFluentBindingDescription<TTarget, TSource> To (Expression<Func<TSource, object>> sourceProperty)
{
_sourceProperty = sourceProperty;
return this;
}
public XFluentBindingDescription<TTarget, TSource> TwoWay ()
{
return this.Mode (BindingMode.TwoWay);
}
public XFluentBindingDescription<TTarget, TSource> OneWay ()
{
return this.Mode (BindingMode.OneWay);
}
public XFluentBindingDescription<TTarget, TSource> OneWayToSource ()
{
return this.Mode (BindingMode.OneWayToSource);
}
public XFluentBindingDescription<TTarget, TSource> Mode (BindingMode mode)
{
_mode = mode;
return this;
}
public XFluentBindingDescription<TTarget, TSource> WithConversion (IValueConverter converter, object converterParameter = null)
{
_converter = converter;
_converterParameter = converterParameter;
return this;
}
public XFluentBindingDescription<TTarget, TSource> WithStringFommat (string stringFormat)
{
_stringFormat = stringFormat;
return this;
}
void IXAppliable.Apply ()
{
if (_self == null) {
throw new ArgumentNullException ("self");
}
if (_targetProperty == null) {
throw new ArgumentNullException ("targetProperty");
}
if (_sourceProperty == null) {
throw new ArgumentNullException ("sourceProperty");
}
Binding binding = Binding.Create<TSource> (_sourceProperty, _mode, _converter, _converterParameter, _stringFormat);
_self.SetBinding (_targetProperty, binding);
}
}
}
using System;
using Xamarin.Forms;
using XForm;
using System.Collections.Generic;
namespace XForm
{
public class XFluentBindingDescriptionSet<TSource> : IXAppliable
{
private readonly List<IXAppliable> _applicables;
public XFluentBindingDescriptionSet ()
{
_applicables = new List<IXAppliable> ();
}
public XFluentBindingDescription<TChildTarget, TSource> Bind<TChildTarget> (TChildTarget childTarget) where TChildTarget : BindableObject {
var desc = new XFluentBindingDescription<TChildTarget, TSource> (childTarget);
_applicables.Add (desc);
return desc;
}
public void Apply ()
{
foreach (var applicable in _applicables)
applicable.Apply ();
}
}
}
using System;
using Xamarin.Forms;
namespace XForm
{
public static class XFluentExtenstion
{
public static XFluentBindingDescriptionSet<TSource> CreateBindingSet<TSource> (this object owner){
return new XFluentBindingDescriptionSet<TSource> ();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment