title: View and View-Model in WPF
body: <p>I've been messing around with MVVM in WPF and have a quick question for folks. Right now I have:</p>
  
  <ul>
  <li>MainWindow which consists of a MenuBar and a UserControl  </li>
  <li>UserControl (mentioned above) contains basically a Grid.</li>
  </ul>
  
  <p>I expose access to Grid Properties as I need in the UserControl, but the User Control knows nothing nor interacts with the MainWindow.</p>
  
  <p>I also have a class I call ViewModel which does manipulation of the MainWindow/UserControl for me. My understanding is that the ViewModel knows about the View (MainWindow/UserControl) and how to manipulate it while the View generally knows nothing about the ViewModel.</p>
  
  <p>If I have that right, here is my question:</p>
  
  <ol>
  <li><p>When I do button clicks on the MainWindow MenuBar I want to perform actions. Right now those actions are bound to say a EventHandler in the MainWindow and the EventHandler instantiates the ViewModel and calls the method for handling like such:</p>
  
  <pre><code>private void RunQueryMenuItemAdvClick(object pSender, RoutedEventArgs pRoutedEventArgs)
  {
      ViewModel vViewModel = new ViewModel(this);
      vViewModel.RunQuery();
  }
  </code></pre></li>
  </ol>
  
  <p>The View Model looks something like this:</p>
  
  <pre><code>    public class ViewModel
  {
      private DataProvider fDataProvider;
  
      private MainWindow fMainWindow;
  
      private BackgroundWorker fQueryWorker = new BackgroundWorker();
  
      public ViewModel(MainWindow pMainWindow)
      {
          fDataProvider = new DataProvider();
          fMainWindow = pMainWindow;
  
          //Query Worker
          fQueryWorker.DoWork += QueryWorkerDoWork;
          fQueryWorker.RunWorkerCompleted += QueryWorkerCompleted;
      }
  
      private void QueryWorkerCompleted(object pSender, RunWorkerCompletedEventArgs pRunWorkerCompletedEventArgs)
      {
          fMainWindow.UserControl_Data.busyIndicator1.IsBusy = false;
          fMainWindow.UserControl_Data.DataToPresent = pRunWorkerCompletedEventArgs.Result;
      }
  
      private void QueryWorkerDoWork(object pSender, DoWorkEventArgs pDoWorkEventArgs)
      {
          pDoWorkEventArgs.Result = this.fDataProvider.GetParticipantsData();
      }
  
      public void RunQuery()
      {
          if (!fQueryWorker.IsBusy)
          {
              fMainWindow.UserControl_Data.busyIndicator1.IsBusy = true;
              fQueryWorker.RunWorkerAsync();
          }
      }
  }
  </code></pre>
  
  <p>Am I way off base with my approach here?</p>
  
  <p><em><strong>EDIT New Solution:</em></strong>
  First, thanks to everyone for their response. I'd like to provide my new solution. This may not be 100% MVVM, but it has to be at least 80% better than what I had!</p>
  
  <p>My ViewModel:</p>
  
  <pre><code>    public class ViewModel : ObservableObject
  {
      private DataProvider fDataProvider;
  
      private BackgroundWorker fQueryWorker = new BackgroundWorker();
  
  
      public ViewModel()
      {
          fDataProvider = new DataProvider();
  
          //Query Worker
          fQueryWorker.DoWork += QueryWorkerDoWork;
          fQueryWorker.RunWorkerCompleted += QueryWorkerCompleted;
      }
  
      //This is my Command for the MainWindow.MenuItem to bind to to run a query
      RelayCommand fRunQueryCommand;
      public ICommand RunQueryCommand
      {
          get
          {
              if (this.fRunQueryCommand == null)
              {
                  this.fRunQueryCommand = new RelayCommand(param =&gt; this.RunQuery(),
                      param =&gt; true);
              }
              return this.fRunQueryCommand;
          }
      }
  
      //This is my Property for the UserControl.progressBar to bind to
      private bool fIsBusy;
      public bool IsBusy
      {
          get { return this.fIsBusy; }
          set
          {
              if (value != this.fIsBusy)
              {
                  this.fIsBusy = value;
                  OnPropertyChanged("IsBusy");
              }
          }
      }
  
      //This is my Property for the UserControl.gridControl.ItemSource to bind to
      private object fSource;
      public object Source
      {
          get { return this.fSource; }
          set
          {
              if (value != this.fSource)
              {
                  this.fSource = value;
                  OnPropertyChanged("Source");
              }
          }
      }
  
      private void QueryWorkerCompleted(object pSender, RunWorkerCompletedEventArgs pRunWorkerCompletedEventArgs)
      {
          this.IsBusy = false;
          Source = pRunWorkerCompletedEventArgs.Result;
      }
  
      private void QueryWorkerDoWork(object pSender, DoWorkEventArgs pDoWorkEventArgs)
      {
          pDoWorkEventArgs.Result = this.fDataProvider.GetParticipantsData();
      }
  
      public void RunQuery()
      {
          if (!fQueryWorker.IsBusy)
          {
              this.IsBusy = true;
              fQueryWorker.RunWorkerAsync();
          }
      }
  </code></pre>
  
  <p>I've removed all of my code from behind the MainWindow and the UserControl and replaced it with XAML for Binding the elements that I needed to the two properties in ViewModel and the 1 Command. Feel free to provide additional feedback on what I may or may not have picked up on with the re-factoring. (Aside from the lack of a Model usage).</p>