0
votes

I have a button in View "A" which already has a bindingSet attached to it (it binds to ViewModel "A"). I have button though which needs to be bound to ViewModel "B".

What is the best way to do this?

1

1 Answers

3
votes

Your ViewModel is your Model for your View.

If that ViewModel is made up of parts, then that can be done by aggregation - by having your ViewModel made up of lots of sub-models - e.g:

// simplified pseudo-code (add INPC to taste)
public class MyViewModel
{
   public MainPartViewModel A {get;set;}
   public SubPartViewModel B {get;set;}
   public string Direct {get;set;}
}

With this done, then a view component can be bound to direct sub properties as well as sub properties of sub view models:

set.Bind(button).For("Title").To(vm => vm.Direct);     
set.Bind(button).For("TouchUpInside").To(vm => vm.A.GoCommand);     
set.Bind(button).For("Hidden").To(vm => vm.B.ShouldHideThings);

As long as each part supports INotifyPropertyChanged then data-binding should "just work" in this situation.


If that approach doesn't work for you... In mvvmcross, you could set up a nested class within the View that implemented IMvxBindingContextOwner and which provided a secondary binding context for your View... something like:

 public sealed class Nested : IMvxBindingContextOwner, IDisposable {

     public Nested() { _bindingContext = new MvxBindingContext(); }

     public void Dispose() {
        _bindingContext.Dispose();
     }

     private MvxBindingContext _bindingContext;
     public IMvxBindingContext BindingContext { get { return _bindingContext; } }
     public Thing ViewModel {
        get { return (Thing)_bindingContext.DataContext; }
        set { _bindingContext.DataContext = value; }
     }
 }

This could then be used as something like:

 _myNested = new Nested();
 _myNested.ViewModel = /* set the "B" ViewModel here */
 var set2 = _myNested.CreateBindingSet<Nested, Thing>();
 // make calls to set2.Bind() here
 set2.Apply();

Notes:

  • I've not run this pseudo-code, but it feels like it should work...
  • to get this fully working, you will also want to call Dispose on the Nested when Dispose is fired on your View
  • given that Views and ViewModels are normally written 1:1 I think this approach is probably going to be harder to code and to understand later.