MvxRecyclerView API Migration

I cannot bind ItemClick from MvxRecyclerView (or its adapter) to a command on my ViewModel using the Fluent API. It works if I put both ItemsSource and ItemClick in XML, so I'm not interested in such a solution.

I used this post as a great landmark ( How to use the free MvvmCross API to bind the TextView of the RecyclerView to the ViewModel property on Android? ) And it all works, except that I cannot bind ItemClick to the MvxRecyclerView (or adapter) to the MainViewModel command , which will lead me to the next snippet (ItemsSource works like a charm, but its property, not the command!).

For brevity, I will not copy the code from the original message ( How to use the free MvvmCross API to bind the TextView of the RecyclerView element to the ViewModel property on Android? ), Suppose that the MainViewModel from this post has been expanded using the ShowItemCommand command as such:

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

and everything else was implemented in accordance with the link provided.

So now, in addition to the ItemsSource, I want to connect the ItemClick to the MvxRecyclerView (or adapter) to the command. The reason they are interchangeable is because MvxRecyclerView simply passes these commands to the adapter.

Apparently this should work ... but it is not:

 adapter.ItemClick = ViewModel.ShowItemCommand; 

This also does not work:

 set.Bind(recyclerView).For(v => v.ItemClick).To(vm => vm.ShowItemCommand); 
+1
source share
2 answers

When creating a custom MvxRecyclerViewHolder you need to make sure that you assign the Click command to the ViewHolder . This is done in the OnCreateViewHolder override of your adapter.


Example for custom 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
source

I can not reproduce your problem. I just created a new project, added a RecyclerView and added the following binding:

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

This works as expected, where ItemClick launches ShowItemCommand . VMs look like this:

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

Source: https://habr.com/ru/post/1257972/


All Articles