Nils
Nils

Reputation: 21

How do I use multiple ViewModels with simple Binding

Is there any possibility to use multiple ViewModels with simple Binding? The idea is to have one ViewModel for each Activity.

Best regards

Nils


I tried out to test with two different ViewModels based on https://github.com/slodge/MvvmCross/tree/master/Sample%20-%20SimpleDialogBinding/SimpleBinding/SimpleDroid, but it seems like there is some problem.

My structure looks like this:

Activity1                   Activity2
    |                       |
    |                       |
    |                       |
ViewModel1              ViewModel2

Both Activites inherit from MvxSimpleBindingActivity.

When I run the program a System.ArgumentException is thrown from MvxBaseSetup. That's the critical part:

   protected IDictionary<Type, Type> GetViewModelViewLookup(Assembly assembly, Type expectedInterfaceType)
    {
        var views = from type in assembly.GetTypes()
                    where !type.IsAbstract
                    && expectedInterfaceType.IsAssignableFrom(type)
                    && !type.Name.StartsWith("Base")
                    let viewModelPropertyInfo = type.GetProperty("ViewModel")
                    where viewModelPropertyInfo != null
                    let viewModelType = viewModelPropertyInfo.PropertyType
                    select new { type, viewModelType };

        return views.ToDictionary(x => x.viewModelType, x => x.type);
    }

I don't really understand why there is a problem with these two different ViewModels.

Upvotes: 2

Views: 958

Answers (1)

Stuart
Stuart

Reputation: 66882

If you are using the simple binding example from MvvmCross without the rest of the framework, and you are using multiple ViewModels, then you will have to find some way to build the lookup table between Views and ViewModels.


The simplest way to do this would be to override the protected abstract IDictionary<Type, Type> GetViewModelViewLookup() method within your setup.

You could replace this with a simple Dictionary like:

return new Dictionary<Type,Type>()
{
{typeof(Activity1), typeof(ViewModel1)},
{typeof(Activity2), typeof(ViewModel2)}
};

Alternatively, if you wanted a more "platform level" fix, then you could implement a generic base class for your activities which set the viewmodel type like:

public class MyBaseActivity<TViewModel>
    : MvxBindingActivityView<MvxNullViewModel>
{
    public new TViewModel ViewModel { get; set; }

    public override object DefaultBindingSource
    {
        get { return ViewModel; }
    }

    protected sealed override void OnViewModelSet()
    {
        // ignored  here
    }
}

Your activities can then inherit as:

public class Activity1 : MyBaseActivity<ViewModel1> {}

and

public class Activity2 : MyBaseActivity<ViewModel2> {}

and the base reflection code would then work.


I'm not sure anyone's used this form of simple binding for anything other than demo - most users have taken onboard the whole platform so far - so please do post other issues as you come across them.


Update: I've now pushed a MvxSimpleBindingActivityView<TViewModel> to GitHub - you can use this as described for MyBaseActivity<TViewModel> above

Upvotes: 1

Related Questions