我无法使用 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 });
}
}