title: MVVM WCF Entity as Model... How to implement propertychange notification in the view model when using Entity as your model
body: <p>I am implementing an MVVM Pattern using Entity as my model...  When I instantiate the Model in the setter I add a propertychanged handler to the object to capture the field changes within the entity object...</p>
  
  <p>When I step through code I find that after I modify the field within the object it is firing the Property Change event multiple times...
  It has led me to believe that I have done something wrong...</p>
  
  <p>I want to use the entity as my model as I do not want to recreate the object as an abstacted object...</p>
  
  <p>Can any find any fault in the code base below that would cause the SelectedCompany.PropertyChanged to fire more then once when the datagrid field is modified...</p>
  
  <p>I was expecting that that the property changed event would only fire once and am a bit perplexed as to why it fires multiple times...</p>
  
  <p>Was it wrong to add the propertyChange event in the Setter...</p>
  
  <p>Here is the ViewModel...</p>
  
  <pre><code>public class CompanyMaintenanceVM : INotifyPropertyChanged
  {
  private ServiceHandler _serviceHandler = new ServiceHandler();
  private bool _ignorePropertyChange = false; //by default we will execute on every property change...
  
  public CompanyMaintenanceVM()
  {
      _companyList = new ObservableCollection&lt;Company&gt;(_serviceHandler.GetCompanies().ToList());
      _selectedCompany = _companyList.First();
      UpdateCommand = new RelayCommand(Update) { IsEnabled = true };
      SearchCommand = new RelayCommand(Search) { IsEnabled = true };
  
      _companyTypeList = new ObservableCollection&lt;CompanyType&gt;(_serviceHandler.GetCompanyTypes().ToList());
  }
  
  private string _selectedKey;
  public string SelectedKey
  {
      get { return _selectedKey; }
      set 
      {
          if (_selectedKey != value)
          {
              _selectedKey = value;
              OnPropertyChanged("SelectedKey");
          }
      }
  }
  
  
  private Company _selectedCompany = new Company();
  public Company SelectedCompany
  {
      get { return _selectedCompany; }
      set
      {
          if (_selectedCompany != value)
          {
              _selectedCompany = value;
              OnPropertyChanged("SelectedCompany");
              SelectedCompany.PropertyChanged += new PropertyChangedEventHandler(SelectedCompany_PropertyChanged);
          }
      }
  }
  
  private ObservableCollection&lt;Company&gt; _companyList;
  public ObservableCollection&lt;Company&gt; CompanyList
  { 
      get { return _companyList; } 
      set 
      { 
          _companyList = value;
          OnPropertyChanged("CompanyList");
      }
  
  }
  
  private ObservableCollection&lt;CompanyType&gt; _companyTypeList;
  public ObservableCollection&lt;CompanyType&gt; CompanyTypeList
  {
      get { return _companyTypeList; }
      set { _companyTypeList = value; }
  }
  
  #region INotifyPropertyChanged Members
  public event PropertyChangedEventHandler PropertyChanged;
  private void OnPropertyChanged(string propertyName)
  {
      if (PropertyChanged != null)
          PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      switch (propertyName)
      {
          case "SelectedKey":
              if (_ignorePropertyChange == false)
              {
                  SelectedKeyChanged();
              }
              _ignorePropertyChange = false;
              break;
          case "SelectedCompany":
              _ignorePropertyChange = true;
              SelectedKey = SelectedCompany.CompanyID;
  
              break;
      }  
  }
  
  void SelectedCompany_PropertyChanged(object sender, PropertyChangedEventArgs e)
  {
      //
  }
  #endregion
  
  private void SelectedKeyChanged()
  {
      var companies = _serviceHandler.GetCompanyByID(SelectedKey);
      if (companies.FirstOrDefault() != null)
      {
          CompanyList = new ObservableCollection&lt;Company&gt;(companies);
          SelectedCompany = CompanyList.First();
      }
      else
      {
          MessageBox.Show("No Company Record Exsists Matching CompanyID " + _selectedKey);
      }
  }
  
  private ICommand _updateCommand;
  public ICommand UpdateCommand
  {
      get
      {
          if (_updateCommand == null)
              _updateCommand = new Updater();
          return _updateCommand;
      }
      set
      {
          _updateCommand = value;
      }
  }
  
  private class Updater : ICommand
  {
      #region ICommand Members
  
      public bool CanExecute(object parameter)
      {
          return true;
      }
      public event EventHandler CanExecuteChanged;
      public void Execute(Object parameter)
      {
  
      }
      #endregion
  }
  
  private void Update()
  {
      _serviceHandler.UpdateRepository(SelectedCompany);
      _serviceHandler.CommitRepository();
  
  }
  
  
  private ICommand _searchCommand;
  public ICommand SearchCommand
  {
      get
      {
          if (_searchCommand == null)
              _searchCommand = new Searcher();
          return _searchCommand;
      }
      set
      {
          _searchCommand = value;
      }
  }
  private class Searcher : ICommand
  {
      #region ICommand Members
  
      public bool CanExecute(object parameter)
      {
          return true;
      }
      public event EventHandler CanExecuteChanged;
      public void Execute(Object parameter)
      {
  
      }
      #endregion
  }
  
  private void Search()
  {
  
  
  
  }
  
  
  }
  </code></pre>
  
  <p>Here is the XAML...</p>
  
  <pre><code>&lt;Window x:Class="XERP.Client.WPF.CompanyMaintenance.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          Title="Company Maintenance" Height="800" Width="600"&gt;
  
      &lt;Grid&gt;
          &lt;Grid.Resources&gt;
  
          &lt;/Grid.Resources&gt;
          &lt;Grid.RowDefinitions&gt;
              &lt;RowDefinition Height="25"&gt;&lt;/RowDefinition&gt;
              &lt;RowDefinition Height="422*"&gt;&lt;/RowDefinition&gt;
          &lt;/Grid.RowDefinitions&gt;
          &lt;Grid.ColumnDefinitions&gt;
              &lt;ColumnDefinition Width="156*"&gt;&lt;/ColumnDefinition&gt;
              &lt;ColumnDefinition Width="422*"&gt;&lt;/ColumnDefinition&gt;
          &lt;/Grid.ColumnDefinitions&gt;
          &lt;TextBlock HorizontalAlignment="Center" Grid.Column="1" Text="Company Maintenance Form"
                     FontSize="13"
                     Margin="130,3,129,5"&gt;&lt;/TextBlock&gt;
          &lt;Menu IsMainMenu="True" Grid.ColumnSpan="2" Margin="2,2,370,2" Width="180"&gt;
              &lt;MenuItem Header="_File" &gt;
                  &lt;MenuItem Header="_New" Command="New"&gt;
                  &lt;/MenuItem&gt;
                  &lt;MenuItem Header="_Save" 
                            IsCheckable="True"
                             Command="{Binding UpdateCommand}" Click="SaveMenuItem_Click"&gt;
                  &lt;/MenuItem&gt;
                  &lt;MenuItem Header="_Exit" Command="Close"&gt;
                  &lt;/MenuItem&gt;
              &lt;/MenuItem&gt;
              &lt;MenuItem Header="_Edit"&gt;
                  &lt;MenuItem Header="_Cut" Command="Cut"&gt;
                  &lt;/MenuItem&gt;
                  &lt;MenuItem Header="_Copy" Command="Copy"&gt;
                  &lt;/MenuItem&gt;
                  &lt;MenuItem Header="_Paste" Command="Paste"&gt;
                  &lt;/MenuItem&gt;
              &lt;/MenuItem&gt;
              &lt;MenuItem Header="_Tools" /&gt;
              &lt;MenuItem Header="_Actions" /&gt;
              &lt;MenuItem Header="_Help" /&gt;
          &lt;/Menu&gt;
  
          &lt;GridSplitter Grid.Row="1" Grid.Column="0" HorizontalAlignment="Right" Width="4" Background="Yellow"/&gt;
  
          &lt;ListView Grid.Row="1" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5"
                   ItemsSource="{Binding CompanyList}" 
                    SelectedItem="{Binding SelectedCompany, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                    SelectionMode="Single"
                    IsSynchronizedWithCurrentItem="True"
                    &gt;
              &lt;ListView.ItemTemplate&gt;
                  &lt;DataTemplate  &gt;
                      &lt;TextBlock Text="{Binding Path=CompanyID, Mode=TwoWay}" Margin="5"/&gt;
                  &lt;/DataTemplate&gt;
              &lt;/ListView.ItemTemplate&gt;
          &lt;/ListView&gt;
          &lt;TabControl Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch" 
                      VerticalAlignment="Stretch"&gt;
              &lt;TabItem Header="Detail"&gt;
                  &lt;Grid&gt;
                      &lt;Grid.RowDefinitions&gt;
                          &lt;RowDefinition Height="46"&gt;&lt;/RowDefinition&gt;
                          &lt;RowDefinition Height="657*"&gt;&lt;/RowDefinition&gt;
                      &lt;/Grid.RowDefinitions&gt;
                      &lt;Grid.ColumnDefinitions&gt;
                          &lt;ColumnDefinition Width="165*"&gt;&lt;/ColumnDefinition&gt;
                          &lt;ColumnDefinition Width="246*"&gt;&lt;/ColumnDefinition&gt;
                      &lt;/Grid.ColumnDefinitions&gt;
                      &lt;StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Orientation="Horizontal" Grid.Row="0" Grid.ColumnSpan="2"&gt;
                          &lt;Button Width="100" Height="20" Margin="10"
                                  Command="{Binding SearchCommand}"&gt;Company...&lt;/Button&gt;
                          &lt;TextBox Width="100" Height="20" Margin=" 10"
                                   Text="{Binding Path=SelectedKey, Mode=TwoWay}"
                                  /&gt;
                      &lt;/StackPanel&gt;
                      &lt;StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Orientation="Vertical" Grid.Row="1" Grid.Column="0"&gt;
                          &lt;TextBlock HorizontalAlignment="Right" VerticalAlignment="Top" Margin="8"&gt;Name:&lt;/TextBlock&gt;
                          &lt;TextBlock HorizontalAlignment="Right" VerticalAlignment="Top" Margin="8"&gt;Description:&lt;/TextBlock&gt;
                          &lt;TextBlock HorizontalAlignment="Right" VerticalAlignment="Top" Margin="8"&gt;Type:&lt;/TextBlock&gt;
                      &lt;/StackPanel&gt;
                      &lt;StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Orientation="Vertical" Grid.Row="1" Grid.Column="1"&gt;
                          &lt;TextBox HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5" Width="200"
                                   Text="{Binding Path=SelectedCompany.Name, Mode=TwoWay}"
                                   /&gt;
                          &lt;TextBox 
                              HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5" Width="200"
                                   Text="{Binding Path=SelectedCompany.Description, Mode=TwoWay}"
                                  /&gt;
                          &lt;ComboBox HorizontalAlignment="Left" Width="200" Margin="5"
                                  ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CompanyTypeList, Mode=TwoWay}"
                                  DisplayMemberPath="Type"  
                                  SelectedValuePath="CompanyTypeID"
                                  SelectedValue="{Binding Path=SelectedCompany.CompanyTypeID, Mode=TwoWay}"/&gt;
                          &lt;TextBox Height="23" Name="ghost" Width="0" /&gt;
                      &lt;/StackPanel&gt;
                  &lt;/Grid&gt;
  
  
              &lt;/TabItem&gt;
              &lt;TabItem Header="List" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"&gt;
                  &lt;Grid&gt;
                      &lt;DataGrid AutoGenerateColumns="False"
                          ItemsSource="{Binding CompanyList}"
                          SelectedItem="{Binding SelectedCompany, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                          SelectionMode="Single"
                          IsSynchronizedWithCurrentItem="True"
  
                          &gt;
                          &lt;DataGrid.Columns&gt;
                              &lt;DataGridTextColumn Binding="{Binding CompanyID, Mode=TwoWay}"
                                                  Header="ID" Width="auto" IsReadOnly="True"/&gt;
                              &lt;DataGridTextColumn Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
                                                  Header="Name" Width="Auto"/&gt;
                              &lt;DataGridTextColumn Binding="{Binding Description, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
                                                  Header="Description" Width="Auto"/&gt;
                              &lt;DataGridComboBoxColumn Header="Type" Width="Auto"
                                  SelectedValueBinding ="{Binding CompanyTypeID, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
                                  DisplayMemberPath="Type"  
                                  SelectedValuePath="CompanyTypeID"&gt;
                                  &lt;DataGridComboBoxColumn.ElementStyle&gt;
                                      &lt;Style TargetType="ComboBox"&gt;
                                          &lt;Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CompanyTypeList, Mode=TwoWay}"/&gt;
                                      &lt;/Style&gt;
                                  &lt;/DataGridComboBoxColumn.ElementStyle&gt;
                                  &lt;DataGridComboBoxColumn.EditingElementStyle&gt;
                                      &lt;Style TargetType="ComboBox"&gt;
                                          &lt;Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CompanyTypeList, Mode=TwoWay}"/&gt;
                                      &lt;/Style&gt;
                                  &lt;/DataGridComboBoxColumn.EditingElementStyle&gt;
                              &lt;/DataGridComboBoxColumn&gt;
                          &lt;/DataGrid.Columns&gt;
                      &lt;/DataGrid&gt;
                      &lt;TextBox Height="23" Name="ghost2" Width="0" /&gt;
                  &lt;/Grid&gt;   
              &lt;/TabItem&gt;
          &lt;/TabControl&gt;
      &lt;/Grid&gt;
  &lt;/Window&gt;
  </code></pre>