title: WPF PropertyChanged code error: cannot implement 'System.ComponentModel.INotifyPropertyChanged
body: <p>i have this code:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Data;
  using System.ComponentModel;
  using System.Collections.Specialized;
  using System.Collections.ObjectModel;
  
  namespace Bix
  {
      public class SettingsDataObject
      {
          private int id;
          public int Id
          {
              get { return id; }
              set { id = value == 0 ? Db.GetNextSettingsId() : value; }
          }
          private string adminEmail; public string AdminEmail { 
              get { return adminEmail; } 
              set { adminEmail = value; } 
          }
          private int state; public int State { get { return state; } set { state = value == 0 ? 1 : value; } }
  
          public object[] GetArray()
          {
              return new object[] { id, adminEmail, state };
          }
  
          public SettingsDataObject()
          {
  
          }
      }
  
      public class SettingsUIObjects : ObservableCollection&lt;SettingsUIObject&gt;,INotifyPropertyChanged
      {
          protected override void InsertItem(int index, SettingsUIObject item)
          {
              base.InsertItem(index, item);
  
              // handle any EndEdit events relating to this item
              item.ItemEndEdit += new SettingsUIObject.ItemEndEditEventHandler(ItemEndEditHandler);
              item.PropertyChanged += new SettingsUIObject.PropertyChangedEventHandler(PropertyChanged);
          }
  
          public void ItemEndEditHandler(IEditableObject sender)
          {
              // simply forward any EndEdit events
              if (ItemEndEdit != null)
              {
                  ItemEndEdit(sender);
              }
          }
  
          public event SettingsUIObject.ItemEndEditEventHandler ItemEndEdit;
          public event SettingsUIObject.PropertyChangedEventHandler PropertyChanged;
      }
  
      public class SettingsDataProvider
      {
          private DataAccessLayer dl;
  
          public SettingsDataProvider()
          {
              dl = new DataAccessLayer();
          }
  
          public SettingsUIObjects GetSettings()
          {
              try
              {
                  SettingsUIObjects objs = new SettingsUIObjects();
  
                  List&lt;SettingsDataObject&gt; objDataObjects = dl.GetSettings();
                  foreach (SettingsDataObject obj in objDataObjects)
                  {
                      objs.Add(new SettingsUIObject(obj));
                  }
  
                  objs.ItemEndEdit += new SettingsUIObject.ItemEndEditEventHandler(SettingsItemEndEdit);
                  objs.CollectionChanged += new
                    NotifyCollectionChangedEventHandler(SettingsCollectionChanged);
                  objs.PropertyChanged += new SettingsUIObject.PropertyChangedEventHandler(SettingsPropertyChanged);
                  return objs;
              }
              catch (Exception) { return new SettingsUIObjects(); }
          }
  
          void SettingsItemEndEdit(IEditableObject sender)
          {
              SettingsUIObject obj = sender as SettingsUIObject;
  
              // use the data access layer to update the wrapped data object
              dl.UpdateSettings(obj.GetDataObject());
          }
  
          void SettingsPropertyChanged(INotifyPropertyChanged sender, PropertyChangedEventArgs e)
          {
              SettingsUIObject obj = sender as SettingsUIObject;
  
              // use the data access layer to update the wrapped data object
              dl.UpdateSettings(obj.GetDataObject());
          }
  
          void SettingsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
          {
              if (e.Action == NotifyCollectionChangedAction.Remove)
              {
                  foreach (object item in e.OldItems)
                  {
                      SettingsUIObject obj = item as SettingsUIObject;
  
                      // use the data access layer to delete the wrapped data object
                      dl.DeleteSettings(obj.GetDataObject());
                  }
              }
              if (e.Action == NotifyCollectionChangedAction.Add)
              {
                  foreach (object item in e.NewItems)
                  {
                      SettingsUIObject obj = item as SettingsUIObject;
  
                      // use the data access layer to delete the wrapped data object
                      dl.UpdateSettings(obj.GetDataObject());
                  }
              }
          }
      }
  
      public class SettingsUIObject : IEditableObject, INotifyPropertyChanged
      {
          private SettingsDataObject obj;
          public SettingsUIObject(SettingsDataObject o)
          {
              obj = o;
          }
  
          public SettingsDataObject GetDataObject()
          {
              return obj;
          }
  
          public int Id { get { return obj.Id; } set { obj.Id = value; } }
          public string AdminEmail { 
              get { return obj.AdminEmail; } 
              set { obj.AdminEmail = value; } 
          }
  
          public delegate void ItemEndEditEventHandler(IEditableObject sender);
  
          public event ItemEndEditEventHandler ItemEndEdit;
  
          #region IEditableObject Members
  
          public void BeginEdit() { }
  
          public void CancelEdit() { }
  
          public void EndEdit()
          {
              if (ItemEndEdit != null)
              {
                  ItemEndEdit(this);
              }
          }
  
          #endregion
  
          public delegate void PropertyChangedEventHandler(INotifyPropertyChanged sender, PropertyChangedEventArgs e);
          public event PropertyChangedEventHandler PropertyChanged;
  
          private void NotifyPropertyChanged(string info)
          {
              if (PropertyChanged != null)
              {
                  PropertyChanged(this, new PropertyChangedEventArgs(info));
              }
          }
  
      }
  }
  </code></pre>
  
  <p>and i keep getting the compile error:</p>
  
  <p>'Bix.SettingsUIObject' does not implement interface member 'System.ComponentModel.INotifyPropertyChanged.PropertyChanged'. 'Bix.SettingsUIObject.PropertyChanged' cannot implement 'System.ComponentModel.INotifyPropertyChanged.PropertyChanged' because it does not have the matching return type of 'System.ComponentModel.PropertyChangedEventHandler'</p>
  
  <p>can anyone tell me why?</p>
  
  <p>thanks</p>
  
  <p>Orson</p>