5
votes

I have discovered a case where Mvvm Cross EditText binding fails to work correctly when the "Do not keep activities" developer setting is enabled using MvvmCross version 3.5.1. Here are the steps to reproduce:

  1. Create a new Core & Droid project using the "Getting Started" Mvvm Cross packages from NuGet.
  2. Add the ZXing.Net.Mobile PCL component from NuGet.
  3. Implement the ViewModel:

        public class FirstViewModel : MvxViewModel
        {
            private readonly IMobileBarcodeScanner _mobileBarcodeScanner;
    
            public FirstViewModel(IMobileBarcodeScanner mobileBarcodeScanner)
            {
                _mobileBarcodeScanner = mobileBarcodeScanner;
            }
    
            private string _barCode = "";
            public string BarCode
            { 
                get { return _barCode; }
                set { _barCode = value; RaisePropertyChanged(() => BarCode); }
            }
    
            private MvxCommand _scanBarCodeCommand;
            public IMvxCommand ScanBarCodeCommand
            {
                get
                {
                    return _scanBarCodeCommand ?? (_scanBarCodeCommand = new MvxCommand(async () => await OnScanBarCode()));
                }
            }
    
            private async Task OnScanBarCode()
            {
                var result = await _mobileBarcodeScanner.Scan();
                if (result != null && !string.IsNullOrEmpty(result.Text))
                {
                    InvokeOnMainThread(() =>
                    {
                        BarCode = result.Text;
                    });
                }
            }
        }
    
  4. Implement the View:

    <?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="fill_parent"
        android:layout_height="fill_parent">
        <EditText
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            local:MvxBind="Text BarCode" />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Scan"
            local:MvxBind="Click ScanBarCodeCommand" />
    </LinearLayout>
    
  5. Initialize the ZXing.Net.Mobile library in the View:

    [Activity(Label = "View for FirstViewModel")]
    public class FirstView : MvxActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.FirstView);
            MobileBarcodeScanner.Initialize(Application);
        }
    }
    
  6. Run the application and scan a bar code. You can use this Barcodesinc bar code generator and scan from your monitor if you don't have any bar codes handy. The scanned bar code should appear in the EditText.
  7. Edit the View XML by adding an android:id to the EditText.

    <?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="fill_parent"
        android:layout_height="fill_parent">
        <EditText
            android:id="@+id/scan_text"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            local:MvxBind="Text BarCode" />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Scan"
            local:MvxBind="Click ScanBarCodeCommand" />
    </LinearLayout>
    
  8. Rebuild and run the application. Now the scanned bar code is not displaying in the EditText. The only change was giving the EditText and android:id. Does anyone understand why adding an android:id would break MvvmCross data binding?

1
What if you set ScannedBarCode only if the value isn't an empty string ? - Giorgi
@Giorgi That doesn't change anything. The EditText is still empty on the screen. The ScannedBarCode property still holds the value I scanned. It's like the ViewModel + View are out of sync. I've included an EDIT above that adds more information I've learned since I originally asked the question. - Trevor Balcom

1 Answers