Thursday, January 24, 2013

Data Binding to specific positions/keys in list and dictionary collections in MvvmCross (MonoTouch, MonoDroid, WP, WinRT)

An issue came in recently request we support indexing for databinding - https://github.com/slodge/MvvmCross/issues/110

To support this, we added a new parser for the source property path binding and the end result is lovely.

As a result, the tip of MvvmCross vNext on Mono for Android now supports Array/IList[T]/ObservableCollection[T] indexed bindings like:

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Mvx.MvxHttpImageView
android:layout_width="50dp"
android:layout_height="50dp"
local:MvxBind="{'ImageUrl':{'Path':'Kittens[2].ImageUrl'}}"
></Mvx.MvxHttpImageView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
local:MvxBind="{'Text':{'Path':'Kittens[2].Name'}}"
android:textAppearance="?android:attr/textAppearanceLarge"
/>
</LinearLayout>

And Dictionary[T1,T2] bindings like:

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Mvx.MvxHttpImageView
android:layout_width="50dp"
android:layout_height="50dp"
local:MvxBind="{'ImageUrl':{'Path':'Lookup[\\'Felix\\'].ImageUrl'}}"
></Mvx.MvxHttpImageView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
local:MvxBind="{'Text':{'Path':'Lookup[\\'Felix\\'].Name'}}"
android:textAppearance="?android:attr/textAppearanceLarge"
/>
</LinearLayout>
view raw gistfile1.xml hosted with ❤ by GitHub
On iOS/MonoTouch those same bindings look like:

public override void ViewDidLoad ()
{
base.ViewDidLoad ();
InitialiseImageHelpers();
this.AddBindings(
new Dictionary<object, string>()
{
{ this._secondImageHelper, "{'ImageUrl':{'Path':'Kittens[2].ImageUrl'}}" },
{ this.SecondLabel, "{'Text':{'Path':'Kittens[2].Name'}}" },
{ this._felixImageHelper, "{'ImageUrl':{'Path':'Lookup[\"Felix\"].ImageUrl'}}" },
{ this.FelixLabel, "{'Text':{'Path':'Lookup[\"Felix\"].Name'}}" },
});
}
view raw gistfile1.cs hosted with ❤ by GitHub

If you want to see this in action, check out the 'specific positions' demo on https://github.com/slodge/MvvmCross-Tutorials/tree/master/Collections (some info at http://slodge.blogspot.co.uk/2013/01/work-in-progress-mvvmcross-lists-sample.html)

2 comments:

  1. Great. Works fine.
    One little notice.
    Your sample in Android:
    local:MvxBind="{'Text':{'Path':'Lookup[\\'Felix\\'].Name'}}"
    And iOs:
    "{'Text':{'Path':'Lookup[\"Felix\"].Name'}}"

    on wp7 will look like
    Text='{Binding Path=Lookup[Felix].Name}'

    With no quotes around Felix. It's just a bit nicer, that you don't need to write escaped quotes like \\'

    ReplyDelete
    Replies
    1. If you think it's important, I'm happy for you to fork and fix - https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Binding/Parse/PropertyPath/MvxSourcePropertyPathParser.cs

      Delete