views:

214

answers:

3

I can use data binding to set the initial Content of a WPF Frame, but subsequent changes to the the bound property (implemented using INotifyPropertyChange) do not seem to change the content.

Also, does anyone know if binding directly to the Content property in this way will cause the bound item to appear in the Frame or NavigationWindow's journal?

Some context: I realize that I should probably be using the NavigationService to interact with the Frame, but I'm attempting to follow the MVVM pattern. It seems like it would be much simpler to databind to the Content property...

A: 

The Frame is a navigation host, so it is more correct to use the NavigationService to navigate to different content. If you use the INotifyPropertyChange, I suppose that you call the related event whenever the content is changed. Then, I also suppose that there is no difficult to use the NavigationService instead.

Maurizio Reginelli
+1  A: 

Many in the WPF community agree that the built-in navigation framework is broken. However, even if you were to use it, binding the Content property is not the correct approach. If you want to use MVVM with navigation you should combine it with the FrontController pattern where the ViewModel dispatches a navigation request to a Controller which then resolves that request for you. There aren't many examples of this concept available because (as I mentioned before) many developers pass on using WPF's built-in navigation.

If you want to look at a very robust navigation engine for WPF, look at nRoute It is a port of the MVC routing engine to WPF.

Mike Brown
A: 

You can use data binding against a Frame, but you need to make sure the Mode for your Binding is set to TwoWay.

XAML:

<Frame Content={Binding Path=MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} />

View Model:

public class MyViewModel : INotifyPropertyChanging, INotifyPropertyChanged
{
  public Page MyProperty
  {
    get
    {
      return _viewModelPage;
    }

    set
    {
      this.OnPropertyChanging("MyProperty");
      _viewModelPage = value;
      this.OnPropertyChanged("MyProperty");
    }
  }
}
Oppositional