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

WCF Dos and Don'ts

Do not inherit interfaces from other interfaces. Interfaces are contracts. Contracts must be explicit, otherwise the flexibility and maintainability of your design would run into issues. An interface is a pure contract definition and should remain explicit and pure. Consider the following example: [ServiceContract] public interface IMyService1 { [OperationContract] void Test1(); } [ServiceContract] public interface IMyService2 : IMyService1 { [OperationContract] void Test2(); } [ServiceBehavior(…)] class MyService : IMyService2, IMyService1 { #region IMyService2 Members public void Test2() { } #endregion #region IMyService1 Members public void Test1() { } #endregion } What happens when you Publish your Service and open its communication channels. If you do the following: ServiceHost serviceHost = new ServiceHost(typeof(MyService, …) ServiceEndpoint ep = serviceHost.AddServiceEndpoint(typeof(IMyService1), typeof(IMyService2)); You will get

How to turn off the annoying adobe updater

Mainly for peole who only installed adobe reader, this becomes an annoying intrusive behavior. Who cares about the updated version of Adobe. 1- Run Adobe Reader 2- Invoke the "Edit" > "Preferences" menu 3- Select the Updater node at the bottom. 4- Select the "Do not download or install updates automatically" 5- Press OK. Done!!!!!!!!!!!! Phew

TF31001 error when connecting to TFS 2010

The Server returned the following error: 246021. An error occurred while processing your request. Technical Information (for Administrator): SQL Server Error 1934 (retry) This error is caused due to SQL Server Server settings of "noCount" and/or "numeric round about" being turned on. Run ssms.exe, right click on the SQl Server node, and invoke the Proerties dialog. Select the "Connections" node, and turn off both items.