title: MVVM Xamarin open new window from ViewModel - How to eliminate reference to the view
body: <p>I want to open a new modal window using the MVVM pattern in a Xamarin Forms app. I have researched opening a new window with the MVVM pattern, which has got me this far, but the thing about windows in Xamarin forms, is they need a reference to the current page (view) to open a new window (new view) from. This forces me to pass a reference to the current page (view) from my viewModel, to my window factory, to launch the new window from. This is a violation of MVVM. My goal is to get rid of any references to views from within my viewModel. That is my question, how do  I do that? My code here happens to be a modal window, but normal windows also need a reference to the page it is launching from. Here is my code and you will see what I mean:</p>
  
  <p>Window Factory (look at the CreateNewWindow method):</p>
  
  <pre><code>public interface IWindowFactory
      {
          void CreateNewWindow();
      }
  
      public class ProductionWindowFactory: IWindowFactory
      {
          Page launchFromPage;
          BackLogViewModel viewModel;
  
          public ProductionWindowFactory(BackLogViewModel ViewModel, Page page)
          {
              viewModel = ViewModel;
              launchFromPage = page;
          }
  
          public void CreateNewWindow()
          {
              AddStoryPage window = new AddStoryPage (new AddStoryViewModel (viewModel));
              launchFromPage.Navigation.PushModalAsync (window);
          }
      }
  }
  </code></pre>
  
  <p>ViewModel that opens a new modal window (look particularly at the AddTask Command):</p>
  
  <pre><code>public class BackLogViewModel : INotifyPropertyChanged
      {
          private IWindowFactory m_windowFactory;
  
          public void DoOpenNewWindow()
          {
              m_windowFactory.CreateNewWindow();
          }
  
          public ObservableCollection&lt;Story&gt; AllMyStories { get; set; }
          private string _updated;
          public string Updated
          {
              get 
              {
                  return _updated;
              }
              set 
              {
                  _updated = value;
                  OnPropertyChanged ();
              }
          }
  
          public Page mypage;
          public BackLogViewModel (Page page)
          {
              Updated = DateTime.Now.ToString();
              mypage = page;
              AllMyStories = new ObservableCollection&lt;Story&gt; ();
  
          }
  
          public ICommand Save
          {
              get {
                  return new Command (() =&gt; {
                      Updated = DateTime.Now.ToString();
                  });
              }
          }
  
          public ICommand AddTask
          {
              get {
                  return new Command ( () =&gt; {
                      m_windowFactory = new ProductionWindowFactory(this, mypage);
                      DoOpenNewWindow();
                  });
              }
          }
  
          public event PropertyChangedEventHandler PropertyChanged;
  
          private void OnPropertyChanged([CallerMemberName] string propertyName = null)
          {
              var handler = PropertyChanged;
              if (handler != null) 
              {
                  handler(this, new PropertyChangedEventArgs (propertyName));
              }
          }
  
          private Command selectCmd;
          public Command Select {
              get {
                  this.selectCmd = this.selectCmd ?? new Command&lt;Story&gt;(p =&gt; 
                      {
                          var monkey = p as Story;
                          if (monkey == null) return;
                          Page z = new Views.StoryPage(p);
                          mypage.Navigation.PushAsync(z);
                      }
                  );
                  return this.selectCmd;
              }
          }
      }
  }
  </code></pre>
  
  <p>How do I get rid of the reference to the current page (view) within my viewModel?</p>