Appendix F. Document Management


Consider the rates of return application shown in Figure F.1, an application used to calculate both average and annualized rates of return.

Figure F.1. The Rates of Return Application


Each row represents a single period of return that's encapsulated by the PeriodReturn type:

// PeriodReturn.cs class PeriodReturn {    string period;    decimal returnRate;    decimal principal;    public PeriodReturn() {}    public PeriodReturn(      string period, decimal returnRate, decimal principal) {      this.period = period;      this.returnRate = returnRate;      this.principal = principal;    }    public string Period {      get { return this.period; }      set { this.period = value; }    }    public decimal ReturnRate {      get { return this.returnRate; }      set { this.returnRate = value; }    }    public decimal Principal {      get { return this.principal; }      set { this.principal = value; }    } }


The following code binds the DataGridView to a list of PeriodReturn objects and detects changes to the data source list in order to recalculate the rates of return:[1]

[1] Data binding and the BindingSource component are covered in Chapter 16: Data Binding Basics and Chapter 17: Applied Data Binding. We haven't implemented INotifyPropertyChanged on PeriodReturn because this application doesn't need item change notifications; for example, we don't ever change the PeriodReturn objects programmatically, only through the grid. See Chapter 16 for the what, why, and how.

// RatesOfReturnForm.Designer.cs partial class RatesOfReturnForm {    ...    void InitializeComponent() {      ...      this.PeriodReturnBindingSource =        new BindingSource(this.components);      ...      // PeriodReturnBindingSource      this.PeriodReturnBindingSource.DataSource =        typeof(SDIRatesOfReturn.PeriodReturn);      this.PeriodReturnBindingSource.ListChanged +=        this.PeriodReturnBindingSource_ListChanged;      ...      // dataGridView      this.dataGridView.DataSource = this.PeriodReturnBindingSource;      ...    }    ...    BindingSource PeriodReturnBindingSource;    DataGridView dataGridView; }


To complete our simple app, we prepopulate the data source with an initial row and handle the data source's ListChanged event to implement the average and annual rates of return calculations:

// RatesOfReturnForm.cs partial class RatesOfReturnForm : Form {    ...    void RatesOfReturnForm_Load(object sender, System.EventArgs e) {      // Add starting principal      this.PeriodReturnBindingSource.List.Add(        new PeriodReturn("start", 0M, 1000M));    }    void PeriodReturnBindingSource_ListChanged(      object sender, ListChangedEventArgs e) {      // Calculate average and annual returns      ...    } }


Thanks to data binding, the development experience was quite enjoyable, until I realized that I needed to save our newly entered rates of return data to disk for later use. Windows Forms and VS05 provide all kinds of support for easily writing data-bound applications, but neither provides any real support for the staple of MFC programmers everywhere: document-based applications.[2]

[2] See Appendix B: Moving from MFC for more information regarding Microsoft Foundation Classes.

Oh, it's easy enough to lay out the File menu and to show the file dialogs. It's even easy to dump the contents of the data source to the disk using the run-time serialization stack in .NET:[3]

[3] The various kinds of serialization stacks provided in .NET are beyond the scope of this book. However, I can recommend Jeffrey Richter's "Run-time Serialization" piece (MSDN Magazine, April 2002), found at http://msdn.microsoft.com/msdnmag/issues/02/04/net/ (http://tinysells.com/39).

// RatesOfReturnForm.cs ... using System.IO; using System.Runtime.Serialization;  using System.Runtime.Serialization.Formatters;  using System.Runtime.Serialization.Formatters.Binary;  [Serializable]  class PeriodReturn {...}  partial class RatesOfReturnForm : Form {    ...    void saveToolStripMenuItem_Click(object sender, EventArgs e) {      if( this.saveFileDialog.ShowDialog(this) != DialogResult.OK ) {        return;      }      string filename = this.saveFileDialog.FileName;      using( Stream stream =        new FileStream(filename, FileMode.Create, FileAccess.Write) ) {        // Serialize object in binary format        IFormatter formatter = new BinaryFormatter();        formatter.Serialize(stream, this.periodReturns);      }    }    ... }


However, document-based applications require a lot more than just showing a file dialog and dumping an object's contents into a file. To satisfy a Windows user's basic expectations, both SDI and MDI applications are required to support a specific set of document-related features.

A minimal document-based application needs to support the following document management behavior:

  • Show the file name of the currently loaded document in the form's caption (for example, Stuff.txt).

  • Prompt users to save a changed document when they attempt to close it without saving.

  • Let users save changes to the current document without providing the file name for each subsequent save. This is the difference between File | Save after the first save and File | Save As.

  • Create new documents, clearing any currently active document.

For completeness, it should also support the following features:

  • Show the user that a document has changed from its last saved state, commonly with an asterisk next to the file name (Stuff.txt*).

  • Register custom file extensions with the shell so that double-clicking a file opens the appropriate application, with the chosen file loaded.

  • Associate the icon for the document type and the application itself.

  • Add opened and saved files to the Start | My Documents menu.

  • Open previously saved files via a most-recently-used (MRU) menu.

  • Handle drag and drop of files from the shell to open the file.

Although Windows Forms provides no implementation of these document-related features, we of the ex-MFC brethren (and sistren) shouldn't let that stop us.




Windows Forms 2.0 Programming
Windows Forms 2.0 Programming (Microsoft .NET Development Series)
ISBN: 0321267966
EAN: 2147483647
Year: 2006
Pages: 216

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net