Skip to main content

Wave Undo

To implement Undo, the simplest way is to use a MemoryStream object in your WaveDisplayForm (MDI Child) and simply serialize the Wave (which should be marked as [Serializable] to the stream and hold on to the stream object.

private MemoryStream _undoStream = new MemoryStream();
private bool _canUndo = false;

public void SaveForUndo()
{
     BinaryFormatter bf = new BinaryFormatter();
     bf.Serialize(_undoStream, wave);

     _undoStream.Flush();

     // This rewinds the stream so that when it is used for deserialization, it's ready to use,
    // otherwise, the deserialization will start deserializing from the end of the stream and would fail.
     _undoStream.Position = 0;
     _canUndo = true;
}
 
public void Undo()
{

     BinaryFormatter bf = new BinaryFormatter();
     _wave = (Wave)bf.Deserialize(_undoStream);
     _canUndo = false;

     // increment the modified counter on the wave (However you implemented this), i did it using the following method on the Wave object
     _wave.DecrementModificationCounter(); // simply does a _modifiedCounter--

     Invalidate();

}
    

Comments

  1. I thought the simpliest way to make
    private Wave _waveUndo = null;
    in WaveDisplayForm. If we need to make many Undo we can make a List (stack).
    Why we need these things with stream?
    Seems I don't understand something...

    ReplyDelete
  2. That would be fine too. The only reason I recommend to use a MemoryStream in general is to not have to copy each element within the Wave object in order to Clone the Wave object. In my long experience this has been always a cause of subtle bugs when someone adds a new data member to Wave and forgets to add the necessary changes for the Cloning method. So for this project, you are right, it's controlled, but in general I always advocate the MemoryStream approach.

    ReplyDelete
  3. Anonymous9:58 PM

    I'm getting an odd error when I try to implement the code. It throws a Serialization Excpetion that Type 'WaveViewer.WaveDisplayForm' in Assembly 'WaveViewer'is not marked as serializable. my Wave class is already marked as [Serializeable] For s&g's I marked WaveMgr and WaveDisplayForm as [Serializable]. Now it says System.Windows.Forms.Form is not marked as Serializable.
    Any suggestions on how to continue troubleshooting?

    ReplyDelete

Post a Comment

Popular posts from this blog