如何将MvxRecyclerView Item的操作连接到ViewModel

时间:2017-02-24 19:20:58

标签: xamarin xamarin.android mvvmcross

我有一个MvxRecyclerView,其中包含以下axml文件:

<?xml version="1.0" encoding="utf-8"?>
<MvvmCross.Droid.Support.V7.RecyclerView.MvxRecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    app:MvxItemTemplate="@layout/item_detail"
    app:MvxBind="ItemsSource Items" />

Correspodning ViewModel的定义如下:

public class ItemsViewModel : MvxViewModel
{
    private ObservableCollection<Models.Item> _items;

    public ObservableCollection<Models.Item> Items
    {
        get { return _items; }
        set
        {
            _items = value;
            RaisePropertyChanged(() => Items);
        }
    }

    public MvxCommand CommandToBeInvokedFromItem
    {
        get
        {
            return new MvxCommand(async () =>
            {
                await ...;
            });
        }
    }
    ...
}

我的item_detail axml定义如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:local="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal">

  <TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"        
    android:textSize="24dp"
    local:MvxBind="Text Name" />

  <ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_delete_forever_black_24dp" 
    local:MvxBind="Click CommandToBeInvokedFromItem"/>

</LinearLayout>

Model.Item的定义如下:

public class Item
{
    public string Name { get; set; }
}

第一个TextView绑定到Item的name属性,该属性非常有效。但我希望ImageButton绑定到MvxRecylerView绑定到的ViewModel上的Command,而不是绑定到Item的属性。 Item只是一个Model而不是ViewModel。我该如何做到这一点?

2 个答案:

答案 0 :(得分:0)

如果需要在单击MvxRecycler中的项目(即整个单元格)时调用该命令,则绑定相对简单。只需将MvxBindMvxRecyclerView的值从ItemsSource Items更改为ItemsSource Items; ItemClick CommandToBeInvokedFromItem即可。然后需要修改CommandToBeInvokedFromItem以接受Item作为类型参数,如下所示:

public MvxCommand<Models.Item> CommandToBeInvokedFromItem
{
    get
    {
        return new MvxCommand<Models.Item>(async () =>
        {
            await ...;
        });
    }
}

如果需要通过点击ImageButton专门提出命令,那么最简单的方法是将CommandToBeInvokedFromItem移至Item,并让Item继承{{1} },或者至少实现MvxViewModel

答案 1 :(得分:0)

Item中创建命令时,将命令移交给ItemsViewModel

public class Item
{
    public string Name { get; set; }        
    public MvxCommand CommandToBeInvokedFromItem {get;}

    public Item(MvxCommand clickCommand)
    {
        CommandToBeInvokedFromItem = clickCommand;
    }
}