Tuesday, May 22, 2012

How do I bind multiple properties in an Android layout element in MvvmCross?

The question....


I'm using MvvmCross to databind my ViewModel to an Android View layout.
From the SimpleBinding example I can see that to bind a value to a property I do this:
  
so Text is bound to the SubTotal property of the ViewModel. But how do I bind to more than one property? In my case I want to bind a ViewModel property called HigherLower to the TextColor attribute of the layout element. I can't add another MvxBind and I can't set MvxBind to an array.

The answer....



The format of the JSON used in the binding expression is a Dictionary of namedMvxJsonBindingDescriptions
public class MvxJsonBindingDescription
{
    public string Path { get; set; }
    public string Converter { get; set; }
    public string ConverterParameter { get; set; }
    public string FallbackValue { get; set; }
    public MvxBindingMode Mode { get; set; }
}
This is used with:
  • the dictionary Key name being the target (View) property for the binding.
  • the binding Path property being the source (DataContext) property for the binding - if Path is not specified then the whole DataContext itself is the binding source.
For Activity/View level axml the DataContext is the ViewModel - but for sub-View axml then the DataContext will normally be a child object of the ViewModel - e.g. inside a ListView the DataContext might be an item inside a List or ObservableCollection owned by the ViewModel.

To specify multiple bindings you can use JSON like:
 {
      'TargetProperty1':{'Path':'SourceProperty1'},
      'TargetProperty2':{'Path':'SourceProperty2'}
 }
For your particular example this might be:
local:MvxBind="
       {
          'Text':{'Path':'SubTotal','Converter':'Float'}, 
          'TextColor':{'Path':'HigherLower','Converter':'MyColorConverter'}
       }"
where your ViewModel is something like:
public class MyViewModel : IMvxViewModel
{
     public float SubTotal { get; set; }

     public bool HigherLower { get; set; }

     // more code here
}
and your converter is something like:
public class MyColorConverter : MvxBaseColorConverter
{
    protected override MvxColor Convert(object value, object parameter, CultureInfo culture)
    {
        return ((bool)value) ? new MvxColor(255,0,0) : new MvxColor(0,255,0);
    }
}
and where that converter is initialized during Setup - e.g. see how the properties of the Converters class are used in TwitterSearch

One sample that shows Multiple Bindings at work is BestSellers - see Click and Text bound in the list itemhttps://github.com/slodge/MvvmCross/blob/master/Sample%20-%20BestSellers/BestSellers/BestSellers.Droid/Resources/Layout/ListItem_Category.axml

No comments:

Post a Comment