Reputation: 1217
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'}" .../>
At the start, the btn
does not have a value to put in it's content, because model is empty.
When the btn
is clicked, it loads the model. It fills model with data and navigates to another page which shows that data.
And when i navigate back (through hardware back button) I'd like btn
to use the value from binding instead of a fallback, because the value is already set. But It doesn't use it and still uses the one provided by FallbackValue argument of binding.
How to ensure, that the page "refreshes" an uses actual values provided by ViewModel?
Upvotes: 2
Views: 6193
Reputation: 1217
Ahh, ok found solution to my problem myself.
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.
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
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