MvvmCross MvxListView ItemClick Enabled Based on property - xamarin

So I have a MvxListView
<Mvx.MvxListView
android:id="#+id/receptionsListView"
android:divider="#drawable/divider"
android:scrollbars="vertical"
android:choiceMode="singleChoice"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left|start"
local:MvxItemTemplate="#layout/item_supplier"
local:MvxBind="ItemsSource ReceptionSuppliersList; ItemClick SelectReceptionCommand;" />
I want to enabled/disabled some Items based on a value from model in the list. Something like
local:MvxBind="ItemsSource ReceptionSuppliersList; ItemClick SelectReceptionCommand; Enabled ReceptionSuppliersList.IsValid" />
From what I've tested this just disabled all my list items because there is no such property ReceptionSuppliersList.IsValid ( it's ReceptionSuppliersList[i].IsValid ). How can I achive this.
I also tried to add the Enabled Property on item_supplier like this
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="0dp"
style="#style/ExtendProTheme.ReceptionItem"
local:MvxBind="Enabled IsValid" >
But it still doesn't work.
Any ideas how can i disable some of the item from my list based on a property?
PS :
My items look like this
public string Username { get; set; }
public string DeviceId { get; set; }
public bool IsValid { get; set; }

You could create a custom adapter to handle the enabling/disabling of list items. You would just need to cast the Adapters ItemsSource to your ViewModels
ReceptionSuppliersList type in the IsEnabled override.
public class CustomAdapter : MvxAdapter
{
public CustomAdapter(Context context)
: base(context)
{
}
public CustomAdapter(Context context, IMvxAndroidBindingContext bindingContext)
: base(context, bindingContext)
{
}
protected CustomAdapter(IntPtr javaReference, JniHandleOwnership transfer) :
base(javaReference, transfer)
{
}
public override bool IsEnabled(int position)
{
var items = ItemsSource as List<TestModel>;
return items[position].IsValid;
}
}
Assign adapter to your MvxListView:
var receptionsListView = FindViewById<MvxListView>(Resource.Id.receptionsListView);
receptionsListView.Adapter = new CustomAdapter(this, BindingContext as IMvxAndroidBindingContext);

That's not a real problem-solve, but it should work for your case:
Add gray overlay on the item to make it look like it's not enabled.
Check whether item is enabled on the method handler for SelectReceptionCommand.
private void OnSelectReceptionCommandExecuted(Reception item)
{
if (!reception.IsEnabled)
{
return;
}
// your code here
}

Related

How to add custom properties for Checkbox in Xamarin Android?

In my Xamarin Android application, I am in need of having some custom properties for Checkbox control. We have default properties like 'Id', 'Text', etc.,
Is it possible to add custom properties programmatically to checkbox?
Well doing this in Xamarin.Android is a Piece of Cake:
First Create your Custom Checkbox by inheriting your class from checkbox control something like this :
public class CustomCheckBox: CheckBox
{
Context mContext;
public CustomCheckBox(Context context) : base(context)
{
Init(context, null);
}
public CustomCheckBox(Context context, Android.Util.IAttributeSet attrs) : base(context, attrs)
{
Init(context, attrs);
}
public CustomCheckBox(Context context, Android.Util.IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
{
Init(context, attrs);
}
public CustomCheckBox(Context context, Android.Util.IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
{
Init(context, attrs);
}
private void Init(Context ctx, Android.Util.IAttributeSet attrs)
{
mContext = ctx;
}
}
Then you can Add your custom properties to it in two different ways
First, you can create an interface and inherit that interface (Suggested one as it helps you in case you need the same property in some other custom control) i.e Something like this :
public class CustomCheckBox : CheckBox , IPropertyCollection
{ ...... }
Where IPropertyCollection is something like this :
public interface IPropertyCollection
{
long FieldId { get; set; }
string FieldName { get; set; }
long PrimaryId { get; set; }
}
Second, you can directly add the properties to your control class and the same will be available inside it something like this
public class CustomCheckBox : CheckBox
{ ......
public string FieldName {get; set;}
}
Hope It helps,
Goodluck!
Revert in case of any queries
On Android, you can custom properties and custom them in the .axml file.
1) add attrs.xml file in your values folder.
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<declare-styleable name="custom">
<attr name="test" format="string" />
<attr name="number" format="integer" />
</declare-styleable>
</resources>
2) here is your MyCheckBox class:
using Android.Content;
using Android.Content.Res;
using Android.Util;
using Android.Widget;
namespace App39
{
public class MyCheckBox : CheckBox
{
public string mText { get; set; }
public int mNumber { get; set; }
public MyCheckBox(Context context, IAttributeSet attrs) : base(context, attrs)
{
TypedArray ta = context.ObtainStyledAttributes(attrs, Resource.Styleable.custom);
string text = ta.GetString(Resource.Styleable.custom_test);
int number = ta.GetInteger(Resource.Styleable.custom_number, -1);
this.mText = text;
this.mNumber = number;
Log.Error("IAttributeSet", "text = " + text + " , number = " + number);
ta.Recycle();
}
}
}
2) custom it in your .axml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<App39.MyCheckBox
android:id="#+id/checkbox"
android:layout_width="match_parent"
android:layout_height="match_parent"
custom:test="111111111"
custom:number="200">
</App39.MyCheckBox>
</RelativeLayout>
4) in your MainActivity:
public class MainActivity : AppCompatActivity
{
MyCheckBox myCheckBox;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
myCheckBox = FindViewById<MyCheckBox>(Resource.Id.checkbox);
//myCheckBox.mNumber;
//myCheckBox.mText;
}
}
Here, I provide a demo for you.

How to wire up MvxRecyclerView Item's actions to ViewModel

I have a MvxRecyclerView which has the following axml file:
<?xml version="1.0" encoding="utf-8"?>
<MvvmCross.Droid.Support.V7.RecyclerView.MvxRecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:MvxItemTemplate="#layout/item_detail"
app:MvxBind="ItemsSource Items" />
Correspodning ViewModel is defined like this:
public class ItemsViewModel : MvxViewModel
{
private ObservableCollection<Models.Item> _items;
public ObservableCollection<Models.Item> Items
{
get { return _items; }
set
{
_items = value;
RaisePropertyChanged(() => Items);
}
}
public MvxCommand CommandToBeInvokedFromItem
{
get
{
return new MvxCommand(async () =>
{
await ...;
});
}
}
...
}
My item_detail axml is defined like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24dp"
local:MvxBind="Text Name" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_delete_forever_black_24dp"
local:MvxBind="Click CommandToBeInvokedFromItem"/>
</LinearLayout>
And Model.Item is defined like this:
public class Item
{
public string Name { get; set; }
}
First TextView binds to Item's name property which works great. But I want the ImageButton to bind to a Command on the ViewModel to which MvxRecylerView is bound rather than to a property of the Item. Item is just a Model and not a ViewModel. How do I accomplish that?
If you need the command to be called on the click of an item in the MvxRecycler (i.e. the entire cell), the binding is relatively simple. Just change the value of MvxBind on the MvxRecyclerView from ItemsSource Items to ItemsSource Items; ItemClick CommandToBeInvokedFromItem. CommandToBeInvokedFromItem would then need to be modified to accept Item as a type parameter, which would look like this:
public MvxCommand<Models.Item> CommandToBeInvokedFromItem
{
get
{
return new MvxCommand<Models.Item>(async () =>
{
await ...;
});
}
}
If the command needs to be raised specifically by clicking on the ImageButton, then the easiest method would be to move CommandToBeInvokedFromItem to Item, and to have Item inherit MvxViewModel, or at least implement INotifyPropertyChanged.
Hand the command over to the Item when you create it in yourItemsViewModel.
public class Item
{
public string Name { get; set; }
public MvxCommand CommandToBeInvokedFromItem {get;}
public Item(MvxCommand clickCommand)
{
CommandToBeInvokedFromItem = clickCommand;
}
}

How to implement Recycler View in MvvmCross using MvxRecyclerView

In MvvmCross, I have an android listview within an activity that works.
I read somewhere that changing the listView to a recyclerView is as simple as changing MvxListView to MvxRecyclerView in my layout .axml file. Trying that gives me the following runtime exception:
Android.Views.InflateException: Binary XML file line #1: Binary XML file line #1: Error inflating class Mvx.MvxRecyclerView
Is there anything that I have to do differently in the code behind or view model when using MvxRecyclerView? Below is my code.
Layout files:
Main.axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Mvx.MvxRecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:id="#+id/words_listview"
local:MvxItemTemplate="#layout/words_listview_row"
local:MvxBind="ItemsSource Words" />
</LinearLayout>
words_listview_row.axml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:p1="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
p1:minWidth="25px"
p1:minHeight="25px"
p1:layout_width="match_parent"
p1:layout_height="match_parent"
p1:id="#+id/relativeLayout1"
p1:background="#FFFFFF">
<TextView
p1:text="Word name"
p1:layout_width="wrap_content"
p1:layout_height="wrap_content"
p1:id="#+id/headingTextView"
p1:width="325dp"
p1:textColor="#000000"
p1:layout_alignParentLeft="true"
p1:textSize="18sp"
p1:paddingLeft="20dp"
p1:paddingTop="15dp"
local:MvxBind="Text Name" />
<TextView
p1:text="Word meaning"
p1:layout_width="match_parent"
p1:layout_height="wrap_content"
p1:layout_below="#id/headingTextView"
p1:id="#+id/detailTextView"
p1:textColor="#8f949a"
p1:layout_alignParentLeft="true"
p1:textSize="16sp"
p1:paddingLeft="20dp"
p1:paddingRight="20dp"
p1:paddingBottom="15dp"
local:MvxBind="Text Meaning" />
</RelativeLayout>
WordViewModel.cs
using MvvmCross.Core.ViewModels;
using VocabBuilder.Core.Models;
using VocabBuilder.Core.Services.Interfaces;
namespace VocabBuilder.Core.ViewModels
{
public class WordViewModel : MvxViewModel
{
private IWordService _wordService;
public MvxObservableCollection<Word> Words { get; set; }
public WordViewModel(IWordService wordService)
{
Words = new MvxObservableCollection<Word>();
_wordService = wordService;
Words.ReplaceWith(_wordService.GetAllWords());
}
}
}
Codebehind/ WordView.cs
using Android.App;
using Android.OS;
using MvvmCross.Droid.Views;
using VocabBuilder.Core.ViewModels;
namespace VocabBuilder.UI.Droid.Views
{
[Activity(Label="Vocab Builder", MainLauncher=true)]
public class WordView : MvxActivity<WordViewModel>
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
}
}
}
Thanks.
EDIT:
Here is my Setup.cs file:
using Android.Content;
using MvvmCross.Core.ViewModels;
using MvvmCross.Droid.Platform;
namespace VocabBuilder.UI.Droid
{
public class Setup : MvxAndroidSetup
{
public Setup(Context applicationContext) : base(applicationContext)
{
}
protected override IMvxApplication CreateApp()
{
return new Core.App();
}
}
}
OK, I got RecyclerView to work easily after replacing MvxListView with MvxRecyclerView. Not sure what the particular problem with your implementation is but i will give you the tidbits of mine and you can try it all out.
My RecyclerView lives in a Fragment inheriting from MvxFragment - a bit different than yours but should not be the determining factor. Here are some Fragment snippets:
public class ListsFragment : MvxFragment<ListsViewModel>
{
...
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
var view = this.BindingInflate(Resource.Layout.fragment_listsfragment, null);
return view;
}
...
}
Here is the axml for fragment_listsfragment:
<?xml version="1.0" encoding="utf-8"?>
<MvvmCross.Droid.Support.V7.RecyclerView.MvxRecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:MvxItemTemplate="#layout/item_list"
app:MvxBind="ItemsSource Lists; ItemClick ShowListItemsCommand" />
I do see a bit of difference in your ViewModel implementation - mine is like this:
public class ListsViewModel : BaseViewModel
{
...
private readonly IListService _listService;
private ObservableCollection<Models.List> _lists;
public ObservableCollection<Models.List> Lists
{
get { return _lists; }
set
{
_lists = value;
RaisePropertyChanged(() => Lists);
}
}
public MvxCommand<Models.List> ShowListItemsCommand
{
get
{
return new MvxCommand<Models.List>(selectedList =>
{
ShowViewModel<ListItemsViewModel>
(new { listId = selectedList.Id });
});
}
}
...
public override async void Start()
{
base.Start();
await InitializeAsync();
}
protected override async Task InitializeAsync()
{
await _listService.InitializeAsync();
Lists = (await _listService.GetListsAsync())
.ToObservableCollection();
}
}
Hope this helps.

CustomFragment in MVVMCross

I have used the following template in my Android application which has navigation drawer has a list of options such as Settings.
https://github.com/MvvmCross/MvvmCross-Samples/tree/master/XPlatformMenus
Source code could be downloaded from the following url
https://github.com/MvvmCross/MvvmCross-Samples
I wonder how could I able to make Settings page as a Dialog or CustomFragment which will look like similar to following image.
One approach that you could make use of is to create a custom implementation of Dialog. Following the XPlatformMenus sample you linked to, you could implement something as follows:
Generic Custom Dialog
This class inherits android Dialog control, and can be used with any XML/AXML layout you want. You could tightly couple it to a particular ViewModel/Layout or you can make it handle a generic ViewModel type. Here is an example of the generic type:
public class CustomDialog : Dialog, IMvxBindingContextOwner
{
public CustomDialog(Context context, int layout, IMvxViewModel viewModel)
: this(context, Resource.Style.CustomDialog)
{
this.BindingContext = new MvxAndroidBindingContext(context, (context as IMvxLayoutInflaterHolder));
ViewModel = viewModel;
Init(layout);
}
public CustomDialog(Context context, int themeResId)
: base(context, themeResId)
{
}
protected CustomDialog(IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
}
protected CustomDialog(Context context, bool cancelable, IDialogInterfaceOnCancelListener cancelListener)
: base(context, cancelable, cancelListener)
{
}
protected CustomDialog(Context context, bool cancelable, EventHandler cancelHandler)
: base(context, cancelable, cancelHandler)
{
}
private void Init(int layout)
{
SetContentView(layout);
}
public override void SetContentView(int layoutResID)
{
var view = this.BindingInflate(layoutResID, null);
base.SetContentView(view);
}
public IMvxBindingContext BindingContext { get; set; }
public object DataContext
{
get { return this.BindingContext.DataContext; }
set { this.BindingContext.DataContext = value; }
}
public IMvxViewModel ViewModel
{
get { return this.DataContext as IMvxViewModel; }
set { this.DataContext = value; }
}
}
XML layout for modal:
<?xml version="1.0" encoding="utf-8" ?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary">
<Button
android:id="#+id/btn_option"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Show"
local:MvxBind="Click ShowSettingsCommand"/>
<Button
android:id="#+id/btn_close"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/btn_option"
android:text="CLOSE"
local:MvxBind="Click ShowCloseCommand"/>
</RelativeLayout>
CustomDialog style:
<resources>
<style name="CustomDialog">
<item name="android:windowIsFloating">true</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>
Custom Presenter
Create a custom presenter to handle the navigation to show/hide the dialog:
public class CustomPresenter : MvxFragmentsPresenter
{
protected IMvxViewModelLoader MvxViewModelLoader => Mvx.Resolve<IMvxViewModelLoader>();
CustomDialog _modal;
public CustomPresenter(IEnumerable<Assembly> AndroidViewAssemblies) : base(AndroidViewAssemblies)
{
}
protected override void ShowActivity(MvxViewModelRequest request, MvxViewModelRequest fragmentRequest = null)
{
if (!Intercept(request))
base.ShowActivity(request, fragmentRequest);
}
protected override void ShowFragment(MvxViewModelRequest request)
{
if (!Intercept(request))
base.ShowFragment(request);
}
private bool Intercept(MvxViewModelRequest request)
{
if (request.ViewModelType == typeof(ThirdViewModel))
{
var activity = Mvx.Resolve<IMvxAndroidCurrentTopActivity>().Activity;
var viewModel = MvxViewModelLoader.LoadViewModel(request, null) as ThirdViewModel;
_modal = new CustomDialog(activity, Resource.Layout.modal_popup, viewModel);
_modal.Show();
return true;
}
if (_modal != null)
{
_modal.Dismiss();
_modal = null;
}
return false;
}
}
Register your custom presenter in the setup class:
protected override IMvxAndroidViewPresenter CreateViewPresenter()
{
var mvxFragmentsPresenter = new CustomPresenter(AndroidViewAssemblies);
Mvx.RegisterSingleton<IMvxAndroidViewPresenter>(mvxFragmentsPresenter);
return mvxFragmentsPresenter;
}
ViewModel
public class ThirdViewModel : BaseViewModel
{
private MvxCommand _showSettingsCommand;
public MvxCommand ShowSettingsCommand =>
_showSettingsCommand ?? (_showSettingsCommand = new MvxCommand(() => ShowViewModel<HomeViewModel>()));
private MvxCommand _showCloseCommand;
public MvxCommand ShowCloseCommand =>
_showCloseCommand ?? (_showCloseCommand = new MvxCommand(() => ShowViewModel<SettingsViewModel>()));
}

MVVMCross Custom Control and Binding

I have created a custom control (CustomCard) which is a subclass of the CardView control. I would like to use this control within my project in different places.
For example, I may place the CustomCard within an xml layout manually, or I may want the CustomCard to be an item in an MvxListView. The key is that I would like to re-use the code as much as possible and benefit from having control over the CustomCard class.
When the CustomCard is instantiated, I am inflating it's layout using the standard layout inflater, see code:
using System;
using Android.Animation;
using Android.Content;
using Android.Support.V7.Widget;
using Android.Util;
using Android.Views;
using Android.Widget;
public class Card : CardView
{
private readonly Context _context;
public Card(Context context)
: base(context)
{
_context = context;
Init();
}
public Card(Context context, IAttributeSet attrs)
: base(context, attrs)
{
_context = context;
Init();
}
private void Init()
{
var inflater = (LayoutInflater) _context.GetSystemService(Context.LayoutInflaterService);
CardView = inflater.Inflate(Resource.Layout.base_card, this);
}
}
Within the layout base_card.xml, I have some elements that I would like to bind using MVVMCross, for example,
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:id="#+id/basecard_title"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Title Text-->
<TextView
android:id="#+id/tv_basecard_header_title"
style="#style/card.title"
android:text="title text"
local:MvxBind="Text Title"
/>
<!-- ImageView -->
<MvxImageView
android:id="#+id/ib_basecard_header_button_expand"
style="#style/card.image"
local:MvxBind="Bitmap ImageBytes,Converter=InMemoryImage"/>
</RelativeLayout>
</FrameLayout>
My actual base_card layout is much more complex.
If I try to use my CustomCard within another XML Layout, none of the binding takes place. I think this is because I am using the standard layout inflater to inflate my base_card within my CustomCard rather than BindingInflate() but I can't be sure.
I have searched on SO and through the forums but I can't find any references to anyone using a custom control that inflates it's own view when instantiated with MVVMCross binding.
Has anyone done it, or am I trying to do something that isn't possible?
I ran into similar issue with CardView control. Since CardView directly inherits from FrameLayout I decided to use implementation almost identical to MvxFrameControl (Thanks Stuart for pointing out MvxFrameControl sample):
public class MvxCardView : CardView, IMvxBindingContextOwner
{
private object _cachedDataContext;
private bool _isAttachedToWindow;
private readonly int _templateId;
private readonly IMvxAndroidBindingContext _bindingContext;
public MvxCardView(Context context, IAttributeSet attrs)
: this(MvxAttributeHelpers.ReadTemplateId(context, attrs), context, attrs)
{
}
public MvxCardView(int templateId, Context context, IAttributeSet attrs)
: base(context, attrs)
{
_templateId = templateId;
if (!(context is IMvxLayoutInflater))
{
throw Mvx.Exception("The owning Context for a MvxCardView must implement LayoutInflater");
}
_bindingContext = new MvxAndroidBindingContext(context, (IMvxLayoutInflater)context);
this.DelayBind(() =>
{
if (Content == null && _templateId != 0)
{
Mvx.Trace("DataContext is {0}", DataContext == null ? "Null" : DataContext.ToString());
Content = _bindingContext.BindingInflate(_templateId, this);
}
});
}
protected MvxCardView(IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
}
protected IMvxAndroidBindingContext AndroidBindingContext
{
get { return _bindingContext; }
}
public IMvxBindingContext BindingContext
{
get { return _bindingContext; }
set { throw new NotImplementedException("BindingContext is readonly in the list item"); }
}
protected View Content { get; set; }
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.ClearAllBindings();
_cachedDataContext = null;
}
base.Dispose(disposing);
}
protected override void OnAttachedToWindow()
{
base.OnAttachedToWindow();
_isAttachedToWindow = true;
if (_cachedDataContext != null
&& DataContext == null)
{
DataContext = _cachedDataContext;
}
}
protected override void OnDetachedFromWindow()
{
_cachedDataContext = DataContext;
DataContext = null;
base.OnDetachedFromWindow();
_isAttachedToWindow = false;
}
[MvxSetToNullAfterBinding]
public object DataContext
{
get { return _bindingContext.DataContext; }
set
{
if (_isAttachedToWindow)
{
_bindingContext.DataContext = value;
}
else
{
_cachedDataContext = value;
if (_bindingContext.DataContext != null)
{
_bindingContext.DataContext = null;
}
}
}
}
}
Usage:
<YourNamespace.MvxCardView
android:layout_width="match_parent"
android:layout_height="match_parent"
local:MvxTemplate="#layout/base_card"
local:MvxBind="DataContext ." />
Note: Using custom implementation also solved my problem with binding click command to CardView control using local:MvxBind="Click MyCommand", which wasn't working until subclassing CardView.

Resources