I am trying to go from an activity to another. I am still learning about MVVMCross so this whole pattern is still very new to me. I am applying it with Xamarin.Android only at the moment.
The setup:
MainDashboardActivity has an Android Design Support library's NavigationView.
The ViewModel MainDashboardViewModel has an IMvxCommand GoToSecondDashboard which is just a simple ShowViewModel to another activity.
The NavigationView has a NavigationItemSelected event. Normally, I would just do this:
navigationView.NavigationItemSelected += (o, e) =>
{
    if(e.MenuItem.ItemId == Resource.Id.SecondDashboardMenu)
    {
        // make new intent to target activity
    }
};
Now I have tucked the navigation logic into the ViewModel's IMvxCommand, and I want to bind it to the NavigationView's event, no longer creating intents and whatnot. How would I achieve this?
I want to use the fluent binding logic in the code file and not in the layout, like how this answer does:
protected override void OnViewModelSet()
{
    SetContentView(Resource.Layout.View_Tip);
    var edit = this.FindViewById<EditText>(Resource.Id.FluentEdit);
    var set = this.CreateBindingSet<TipView, TipViewModel>();
    set.Bind(edit).To(vm => vm.SubTotal);
    set.Apply();
    // for non-default properties use 'For':
    // set.Bind(edit).For(ed => ed.Text).To(vm => vm.SubTotal);
    // you can also use:
    //   .WithConversion("converter", "optional parameter")
    //   .OneTime(), .OneWay() or .TwoWay()
}
But NavigationItemSelected is an event. I have not been able to find a way to bind events to commands. There is also the logic of filtering ItemId before that can happen, so it's not going to even be a straightforward event-to-command binding.
I am not sure if this is the correct approach to this. All I want is to bind menu taps to commands in the code file instead of the layout file.
Since there are no Binding Targets defined for NavigationView, you won't be able to bind as Cyriac describes in his post.
What a target binding does internally is simply subscribe to an event and react to it and exposing that data as a property.
So since there is no way to take an ItemsSource and bind to a NavigationView currently, you have to do something like you are doing already, hooking an EventHandler up to the event, and call directly into your ViewModel, i.e. invoking a Command. This looks something like this:
navigationView.NavigationItemSelected += ItemSelected;
private void ItemSelected(object sender, NavigationItemSelectedEventArgs args)
{
    ViewModel.NavigateCommand.Execute(args.MenuItem.TitleFormatted.ToString());
}
Then in your ViewModel in your Command:
private void DoNavigateCommand(string title)
{
    if (title == "Derp")
        ShowViewModel<DerpViewModel>();
}
Alternatively you could wrap this code in a Target Binding. You can see how these are implemented in the official MvvmCross github repository.
I found an answer by someone else on http://crosscuttingconcerns.com/MvvmCross-Fluent-Databinding , which you should try out. I think you just cant reference directly the Event, rather have to use the string.
protected override void OnViewModelSet ()
{
        SetContentView (Resource.Layout.TermsPage);
        var set = this.CreateBindingSet<TermsView, TermsViewModel>();
        set.Bind(FindViewById<Button>(Resource.Id.acceptTermsButton))
            .For("Click")
            .To(vm => vm.AcceptTermsCommand);
        set.Apply();
}
Well of course you have do adjust it depending on your event.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With