我无法使用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);
答案 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")]