The example implementation of IEditableObject on MSDN (here) shows a pretty straightforward way to accomplish it.  I think this implementation is a little clearer, but on the other hand Microsoft probably tested theirs:
public class MyObject : ViewModelBase, IEditableObject
{
   private struct MyData
   {
      string Foo,
      string Bar
   };
   private MyData Saved = new MyData()
   private MyData Current = Saved;
   public string Foo
   {
      get { return Current.Foo; }
      set
      {
         Current.Foo = value;
         OnPropertyChanged("Foo");
      }
   }
   public string Bar
   {
      get { return Current.Bar; }
      set
      {
         Current.Bar = value;
         OnPropertyChanged("Bar");
      }
   }
   public void BeginEdit() 
   { 
      if (Current == Saved)
      {
         Current = new MyData(); 
         Current.Foo = Saved.Foo;
         Current.Bar = Saved.Bar;
      }
   }
   public void CancelEdit() 
   {
      if (Current != Saved)
      { 
         Current = Saved;
         OnPropertyChanged("Foo");
         OnPropertyChanged("Bar");
      }
   }
   public void EndEdit()
   {
      if (Current != Saved)
      {
         Saved = Current;
      }
   }
}
Using this pattern, Current always contains the current values of the object irrespective of its editing state, which makes the property accessors easy to implement; the IEditableObject methods just switch around what Current is.
It's reasonably easy to implement even a quite large number of properties; you just have to be sure to update BeginEdit and CancelEdit when you add a new property.