MvxRecyclerView Fluent API绑定

时间:2017-03-21 21:05:41

标签: android xamarin binding xamarin.android mvvmcross

我无法使用Fluent API将ItemClick从MvxRecyclerView(或其适配器)绑定到我的ViewModel上的命令。如果我将ItemsSource和ItemClick都放在XML中,那么它就有效,所以我对这样的解决方案不感兴趣。

我使用这篇文章作为一个很好的指南(How to use the MvvmCross fluent API to bind a RecyclerView item's TextView to a property of its ViewModel on Android?)并且所有这些都有效,除了我无法将MvxRecyclerView(或适配器)上的ItemClick绑定到MainViewModel的命令,这将带我到下一个片段(ItemsSource就像一个魅力但它的属性而不是命令!)。

为了简洁起见,我不会复制原始帖子(How to use the MvvmCross fluent API to bind a RecyclerView item's TextView to a property of its ViewModel on Android?)中的代码,因此假设该帖子中的MainViewModel已使用ShowItemCommand命令进行了增强:

public class MainViewModel : MvxViewModel
{
    private IEnumerable<ViewModelItem> _viewModelItems;
    public IEnumerable<ViewModelItem> ViewModelItems
    {
        get { return _viewModelItems; }
        set { SetProperty(ref _viewModelItems, value); }
    }    

    public MvxCommand<ViewModelItem> ShowItemCommand
    {
        get
        {
            return new MvxCommand<ViewModelItem>(selectedItem =>
            {
                ShowViewModel<ViewModelItem>
                (new { itemId = selectedItem.Id });
            });
        }
    }
}

其他所有内容都按照引用的帖子实现。

现在,除了ItemsSource之外,我还希望将MvxRecyclerView(或适配器)上的ItemClick连接到命令。这些可以互换的原因是MvxRecyclerView只是将这些命令传递给适配器。

显然,这应该有效......但事实并非如此:

adapter.ItemClick = ViewModel.ShowItemCommand;

这也不起作用:

set.Bind(recyclerView).For(v => v.ItemClick).To(vm => vm.ShowItemCommand);

2 个答案:

答案 0 :(得分:3)

创建自定义MvxRecyclerViewHolder时,您需要确保将Click命令分配给ViewHolder。这是在自定义适配器的OnCreateViewHolder覆盖中完成的。

自定义ViewHolder

的示例
public class MyAdapter : MvxRecyclerAdapter
{
    public MyAdapter(IMvxAndroidBindingContext bindingContext)
        : base(bindingContext)
    {
    }

    public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
    {
        var itemBindingContext = new MvxAndroidBindingContext(parent.Context, this.BindingContext.LayoutInflaterHolder);
        var view = this.InflateViewForHolder(parent, viewType, itemBindingContext);

        return new MyViewHolder(view, itemBindingContext)
        {
            Click = ItemClick,
            LongClick = ItemLongClick
        };
    }
}

答案 1 :(得分:0)

我无法重现您的问题。我刚刚创建了一个新项目,添加了一个RecyclerView并添加了以下绑定:

ItemClick

此功能与预期一致,ShowItemCommand触发public class ViewModelItem : MvxViewModel { public void Init(string itemId) { Mvx.Trace($"Showing {itemId}"); } public string Id { get; set; } } public class FirstViewModel : MvxViewModel { public FirstViewModel() { ViewModelItems = new ViewModelItem[] { new ViewModelItem { Id = "Hello"}, new ViewModelItem { Id = "World"}, new ViewModelItem { Id = "Foo"}, new ViewModelItem { Id = "Bar"}, new ViewModelItem { Id = "Baz"} }; } private IEnumerable<ViewModelItem> _viewModelItems; public IEnumerable<ViewModelItem> ViewModelItems { get { return _viewModelItems; } set { SetProperty(ref _viewModelItems, value); } } public MvxCommand<ViewModelItem> ShowItemCommand => new MvxCommand<ViewModelItem>(DoShowItem); private void DoShowItem(ViewModelItem item) { ShowViewModel<ViewModelItem>(new { itemId = item.Id }); } } 。 VM的外观如下:

//a[contains(@class, "btn") and contains(.,"Add a new connection")]