0

I have the following two models in my app:

public class AppSettings : INotifyPropertyChanged
{
   private Units _mainUnits; // Units is an Enum.
   public Units MainUnits {
     get { return _mainUnits; }
     set {
       if (!_mainUnits != value) {
         _mainUnits = value;
         this.OnPropertyChanged("MainUnits");
       }
     }
   }

   // Standard PropetyChanged event, etc. elided (using NotifyPropertyWeaver).
   [...]
}

public class Ride : INotifyPropertyChanged
{
   private double _rideDistance;
   public double RideDistance {
     get { return _rideDistance; }
     set { 
       if (!_rideDistance != value) {
         _rideDistance = value;
         this.OnPropertyChanged("RideDistance");
       }
     }
   }

   // Standard PropetyChanged event, etc. elided (using NotifyPropertyWeaver).
   [...]
}

Then on my application page I have a TextBlock bound to the RideDistance property that uses an IValueConverter that converts the RideDistance from metres to either km or miles depending on the value of the MainUnits enum.

This works fine as the values for the Ride model change, however I want to refresh the page when the user changes the AppSettings.MainUnit property on the settings page and navigates "back" to the display page.

For example:

  1. App starts, page loads, AppSettings.MainUnits == Units.Imperial, RideDistance shows as "1.3 miles".
  2. User navigates to Settings page, and changes AppSettings.MainUntis to Units.Metric.
  3. User presses "Back" to go back to first page.
  4. Page should now list RideDistance as 2.1km, however it still lists it in miles.

Restarting the app results in the desired behaviour as does explicitly navigating to the first page, but using the back button doesn't.

How can I force a refresh of the bound properties when the user uses the back button?

There's a small working app demonstrating this on the "RefreshProperties" branch of my FodyTest project:

RefreshProperties Branch

enter image description here

Click the settings icon to change the units, navigate back to the start page, notice no difference, then refresh the page using the refresh button...

Zhaph - Ben Duguid
  • 26,785
  • 5
  • 80
  • 117

1 Answers1

2

A somewhat dirty hack: - Add a method X() to the Ride class which calls OnPropertyChanged("RideDistance"); - In AppSettings.set_MainUnits call Ride.X();

EDIT: Another somewhat dirty approach which rebinds all Bindings of the page: - In MainPage's OnNavigatedTo, if(e.NavigationMode==Back) {DataContext=null; DataContext=myViewModel;}

HDW Production
  • 1,402
  • 10
  • 13
  • yeah, I had considered something like this, I also considered hooking the changed event for the MainUnits and tweaking the value of Ride, but there are a couple of properties that are affected by this as well as a couple of pages it happens on – Zhaph - Ben Duguid Jul 31 '12 at 07:29
  • Then how about this (might cause some flicker): In MainPage's OnNavigatedTo, if(e.NavigationMode==Back) {DataContext=null; DataContext=myViewModel;} – HDW Production Jul 31 '12 at 08:28
  • Hmm, just tried the option in your comment, and it seems to work - the flicker (if any) is hidden by the transition animation (at least on the emulator, I need to deploy onto my phone to really confirm) - if you include this in your answer there will be at least an upvote in it ;) – Zhaph - Ben Duguid Jul 31 '12 at 11:56