mishan
mishan

Reputation: 1217

Navigation Back & MVVM - How to refresh WP8 page databinding

I'm doing a WP8 App (C#/XAML).

In my view I specify a button, which contect is set by binding with a callback, for the start of an app, when the VM is not fully loaded.

MVVM looks like:

ViewModel
---------
 + Model
   -----
    +Property

And is created in App.xaml.cs like this:

public static MainViewModel ViewModel
    {
        get
        {
            if (viewModel == null)
            {
                viewModel = new MainViewModel();
            }
            return viewModel;
        }
    }

And set to the page as datacontext in contructor of the page:

DataContext = App.ViewModel;

And button:

<Button x:Name="btn" Content="{Binding Model.Property, FallBackValue='click to load'}" .../>

How to ensure, that the page "refreshes" an uses actual values provided by ViewModel?

Upvotes: 2

Views: 6193

Answers (2)

mishan
mishan

Reputation: 1217

Ahh, ok found solution to my problem myself.

THE PROBLEM

If you're using static Datacontext (if the Viewmodel class you use is created as static), then when you navigate back to the page, the databinding won't update (at least that is how it was in my case).

I use same datacontext (ViewModel containing multiple models and inside some collections and properties) for multiple pages. But when I navigated back to the page through hardware back button, the databinding was not updated.

The content of a button/textblock is stuck at the old value, even though you changed it to some new one.

Solution

Override the OnNavigatedTo Method, and set databinding there instead in contructor. This way you can be sure, that the databinding is always "fresh" and updated.

Inside the page class in code-behind (the .xaml.cs file sticked to your .xaml page) write this:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
   base.OnNavigatedTo(e);        //can be left out, base method is empty
   DataContext = null;           //setting datacontext empty at first
   DataContext = App.ViewModel;  //and setting it to the static ViewModel i created
}

This way, the DataContext is always first set to null, when I come to the page (so that the old values clean and there is nothing to bind from).

And shortly after that, i put the original DataContext back, so it has something to bind from again.

The step with null is necessary, because i need the datacontext property to change, otherwise if I just point again at the same obect that is already set as dataContext, nothing will happen.

Upvotes: 4

Shivangi Gupta
Shivangi Gupta

Reputation: 876

I guess your ViewModel would be implementing INotifyPropertyChanged. To refresh the data binding you just need to raise property change event implemented in your model. In OnNavigatedTo event of your page check if Model is empty or not. If not raise property change

In your view model

 public class ViewModel:INotifyPropertyChanged
 {   
    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion
  }

In your page

  protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
  {
        if (App.ViewModel != null)
            App.ViewModel.NotifyPropertyChanged("Name of property");
  }

Upvotes: 2

Related Questions