MVVMCross:如何将Xamarin.Android事件绑定到ViewModel命令

时间:2016-06-17 08:21:41

标签: c# xamarin xamarin.android mvvmcross

我正试图从一项活动转到另一项活动。我还在学习MVVMCross,所以整个模式对我来说还是很新的。我目前只在Xamarin.Android上应用它。

设置:

  1. MainDashboardActivity有一个Android设计支持库' NavigationView.

  2. ViewModel MainDashboardViewModelIMvxCommand GoToSecondDashboard,这只是另一项活动的简单ShowViewModel

  3. NavigationView有一个NavigationItemSelected事件。通常情况下,我会这样做:

    navigationView.NavigationItemSelected += (o, e) =>
    {
        if(e.MenuItem.ItemId == Resource.Id.SecondDashboardMenu)
        {
            // make new intent to target activity
        }
    };
    

    现在我已将导航逻辑隐藏到ViewModel的IMvxCommand中,我想将它绑定到NavigationView的事件,不再创建意图和诸如此类的东西。我怎么做到这一点?

    我想在代码文件中使用流畅的绑定逻辑而不是布局,就像this answer的做法一样:

    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()
    }
    

    但是NavigationItemSelected是一个事件。我无法找到将事件绑定到命令的方法。在可能发生之前还有过滤ItemId的逻辑,因此它甚至不是一个简单的事件到命令绑定。

    我不确定这是否是正确的方法。我想要的只是将菜单点击绑定到代码文件中的命令而不是布局文件。

2 个答案:

答案 0 :(得分:6)

由于没有为NavigationView定义绑定目标,因此您无法绑定为Cyriac describes in his post

目标绑定在内部执行的操作只是订阅事件并对其作出反应并将该数据作为属性公开。

因为目前没有办法获取ItemsSource并绑定到NavigationView,你必须做一些类似于你已经做过的事情,将EventHandler挂到{ {1}},直接调用event,即调用命令。这看起来像这样:

ViewModel

然后在navigationView.NavigationItemSelected += ItemSelected; private void ItemSelected(object sender, NavigationItemSelectedEventArgs args) { ViewModel.NavigateCommand.Execute(args.MenuItem.TitleFormatted.ToString()); } 中的ViewModel

Command

或者,您可以将此代码包装在Target Binding中。您可以看到这些是如何实现的in the official MvvmCross github repository

答案 1 :(得分:3)

我在http://crosscuttingconcerns.com/MvvmCross-Fluent-Databinding上找到了其他人的答案,您应该尝试一下。我想你不能直接引用Event,而是必须使用字符串。

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();
}

当然,您可以根据自己的事件进行调整。