MvxRecyclerView Fluent API binding



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

我用这篇文章作为一个很好的指南(如何使用MvvmCross流畅的API将RecyclerView项目的TextView绑定到Android上ViewModel的属性?),所有这些都有效,除了我无法将MvxRecyclerView(或适配器)上的ItemClick绑定到MainViewModel的命令,这将带我进入下一个片段(ItemsSource就像一个魅力,但它是一个属性而不是一个命令!)。

为了简洁起见,我不会从原始帖子中复制代码(如何使用 MvvmCross fluent API 将 RecyclerView 项的 TextView 绑定到其在 Android 上的 ViewModel 的属性?),因此假设该帖子中的 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);

创建自定义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
};
}
}

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

var set = this.CreateBindingSet<FirstView, FirstViewModel>();
set.Bind(recyclerView).For(v => v.ItemsSource).To(vm => vm.ViewModelItems);
set.Bind(recyclerView).For(v => v.ItemClick).To(vm => vm.ShowItemCommand);
set.Apply();

这就像预期的那样工作,其中ItemClick触发ShowItemCommand。VM 的外观如下所示:

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

最新更新