Mvvmcross: Binding in an MvxFragment is incorrectly resetting modified values

Created on 19 Mar 2016  路  2Comments  路  Source: MvvmCross/MvvmCross

I have run into an issue with binding in a fragment that I believe is incorrect, and possibly a bug. The first time a fragment with bound EditText views is shown, everything works as expected. The second time the same fragment is shown, the form builds as expected, but then calls to the ViewModel property setters reset the values to those from when it was shown previously.

Oddly enough, we discovered that removing the android:id attribute from the element in the layout axml file removes the unwanted behavior for the field in question.

I have isolated the issue in a solution that can be found @ https://github.com/jrmcnair/MvvmCross_BindingIssue.git

Steps to reproduce

  1. Run BindingIssue.Droid Project
  2. Select "Show Second View" button
  3. Modify text in both fields
  4. Select "Show First View" button
  5. Select "Show Second View" button

    Expected behavior

Since the SecondViewModel.Init method resets the values for the two bound properties in the View Model, I would expect the initialized values "First" and "Second" to appear in their respective fields.

Actual behavior

The Second field is correctly showing the View Model property value, but the first field is incorrectly showing the modified value from the previous display of the view.

The first field has the android:id attribute in the layout axml, and the second field does not.

Configuration

Version: 4.0.0

Platform: Android

Plugins in addition to MvvmCross.StarterPack:
MvvmCross.Droid.Support.V7.AppCompat v4.0.2
MvvmCross.Droid.Support.V7.Fragging v4.0.1
Xamarin.Android.Support.v7.AppCompat v23.1.1
Xamarin.Android.Support.v4 v23.1.1
MvvmCross.Plugin.Json v4.0.0
Newtonsoft.Json v8.0.2

needs-investigation bug up-for-grabs

Most helpful comment

This has to do with our current fragment caching logic.

Overriding the method ShouldReplaceCurrentFragment of MvxCachingFragmentCompatActivity and setting the FragmentReplaceMode to ReplaceFragmentAndViewModel should fix the issue.

What that would do is to recreate the fragment instead of retrieving the existing cached instance.

My advise is to use ReplaceFragmentAndViewModel for every Fragment that has inputs and that kind of controls for now (caching logic should be improved to handle this scenario, just as @thefex says)

All 2 comments

I think I see what's wrong there. If "id" is passed Android caches UI elements values automatically (onDestroy) - and it looks like this restore is invoked after binding system binds it's values. We need to find place when this exactly happens and somehow invoke binding "refresh".

This has to do with our current fragment caching logic.

Overriding the method ShouldReplaceCurrentFragment of MvxCachingFragmentCompatActivity and setting the FragmentReplaceMode to ReplaceFragmentAndViewModel should fix the issue.

What that would do is to recreate the fragment instead of retrieving the existing cached instance.

My advise is to use ReplaceFragmentAndViewModel for every Fragment that has inputs and that kind of controls for now (caching logic should be improved to handle this scenario, just as @thefex says)

Was this page helpful?
0 / 5 - 0 ratings