由DrawTool提供的DocToolKit包括以下内容:

DrawTools实现了一些特别的应用程序功能
- DocManager 类: 处理文件操作:打开,新建,保存,更新窗体标题,为Windows Shell注册文件类型。创建这个类引用了Chris Sells 的文章 Creating Document-Centric Applications in Windows Forms 。
- DragDropManager 类: 在Windows Form应用程序中允许你通过拖拽的方式从浏览器(文件浏览器)中打开文件。
- MruManager 类: 管理大多数最近使用的文件列表。
- PersistWindowState 类: 允许你把最近一次的窗口状态保存到注册表 ,在窗体载入的时候重新获得。来源: Saving and Restoring the Location, Size and Windows State of a .NET Form By Joel Matthias.
这4个类是窗体程序通用的,我这里进行了初步的使用小结,实际上非常简单。
DocManager提供了类似MFC中序列化和反序列号的操作
/// <summary>
/// Document manager. Makes file-related operations:
/// open, new, save, updating of the form title,
/// registering of file type for Windows Shell.
/// Built using the article:
/// Creating Document-Centric Applications in Windows Forms
/// by Chris Sells
/// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms09182003.asp【已失效】
/// </summary>
在具体的使用过程中,是Csharp独特的委托机制。
// Subscribe to DocManager events.
docManager.SaveEvent += docManager_SaveEvent;
docManager.LoadEvent += docManager_LoadEvent;
就配置使用这块来看,将docManager定义并初始化后,着重是直接操作两个Event。
private void docManager_SaveEvent(object sender, SerializationEventArgs e)
{
// DocManager asks to save document to supplied stream
try
{
e.Formatter.Serialize(e.SerializationStream, drawArea.GraphicsList);
}
catch (ArgumentNullException ex)
{
HandleSaveException(ex, e);
}
catch (SerializationException ex)
{
HandleSaveException(ex, e);
}
catch (SecurityException ex)
{
HandleSaveException(ex, e);
}
}
private void docManager_LoadEvent(object sender, SerializationEventArgs e)
{
// DocManager asks to load document from supplied stream
try
{
drawArea.GraphicsList = (GraphicsList)e.Formatter.Deserialize(e.SerializationStream);
}
catch (ArgumentNullException ex)
{
HandleLoadException(ex, e);
}
catch (SerializationException ex)
{
HandleLoadException(ex, e);
}
catch (SecurityException ex)
{
HandleLoadException(ex, e);
}
}
可以直接将控件进行序列化操作。它的代码中提供了较为详细的操作说明
/*
Using:
1. Write class which implements program-specific tasks. This class keeps some data,
knows to draw itself in the form window, and implements ISerializable interface.
Example:
[Serializable]
public class MyTask : ISerializable
{
// class members
private int myData;
// ...
public MyTask()
{
// ...
}
public void Draw(Graphics g, Rectangle r)
{
// ...
}
// other functions
// ...
// Serialization
// This function is called when file is loaded
protected GraphicsList(SerializationInfo info, StreamingContext context)
{
myData = info.GetInt32("myData");
// ...
}
// Serialization
// This function is called when file is saved
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("myData", myData);
// ...
}
}
Add member of this class to the form:
private MyClass myClass;
2. Add the DocManager member to the owner form:
private DocManager docManager;
3. Add DocManager message handlers to the owner form:
private void docManager_ClearEvent(object sender, EventArgs e)
{
// DocManager executed New command
// Clear here myClass or create new empty instance:
myClass = new MyClass();
Refresh();
}
private void docManager_DocChangedEvent(object sender, EventArgs e)
{
// DocManager reports that document was changed (loaded from file)
Refresh();
}
private void docManager_OpenEvent(object sender, OpenFileEventArgs e)
{
// DocManager reports about successful/unsuccessful Open File operation
// For example:
if ( e.Succeeded )
// add e.FileName to MRU list
else
// remove e.FileName from MRU list
}
private void docManager_LoadEvent(object sender, SerializationEventArgs e)
{
// DocManager asks to load document from supplied stream
try
{
myClass = (MyClass)e.Formatter.Deserialize(e.SerializationStream);
}
catch ( catch possible exceptions here )
{
// report error
e.Error = true;
}
}
private void docManager_SaveEvent(object sender, SerializationEventArgs e)
{
// DocManager asks to save document to supplied stream
try
{
e.Formatter.Serialize(e.SerializationStream, myClass);
}
catch ( catch possible exceptions here )
{
// report error
e.Error = true;
}
}
4. Initialize docManager member in the form initialization code:
DocManagerData data = new DocManagerData();
data.FormOwner = this;
data.UpdateTitle = true;
data.FileDialogFilter = "MyProgram files (*.mpf)|*.mpf|All Files (*.*)|*.*";
data.NewDocName = "Untitled.mpf";
data.RegistryPath = "Software\MyCompany\MyProgram";
docManager = new DocManager(data);
docManager.SaveEvent += docManager_SaveEvent;
docManager.LoadEvent += docManager_LoadEvent;
docManager.OpenEvent += docManager_OpenEvent;
docManager.DocChangedEvent += docManager_DocChangedEvent;
docManager.ClearEvent += docManager_ClearEvent;
docManager.NewDocument();
// Optionally - register file type for Windows Shell
bool result = docManager.RegisterFileType("mpf", "mpffile", "MyProgram File");
5. Call docManager functions when necessary. For example:
// File is dropped into the window;
// Command line parameter is handled.
public void OpenDocument(string file)
{
docManager.OpenDocument(file);
}
// User Selected File - Open command.
private void CommandOpen()
{
docManager.OpenDocument("");
}
// User selected File - Save command
private void CommandSave()
{
docManager.SaveDocument(DocManager.SaveType.Save);
}
// User selected File - Save As command
private void CommandSaveAs()
{
docManager.SaveDocument(DocManager.SaveType.SaveAs);
}
// User selected File - New command
private void CommandNew()
{
docManager.NewDocument();
}
6. Optionally: test for unsaved data in the form Closing event:
private void MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if ( ! docManager.CloseDocument() )
e.Cancel = true;
}
7. Optionally: handle command-line parameters in the main function:
[STAThread]
static void Main(string[] args)
{
// Check command line
if( args.Length > 1 )
{
MessageBox.Show("Incorrect number of arguments. Usage: MyProgram.exe [file]", "MyProgram");
return;
}
// Load main form, taking command line into account
MainForm form = new MainForm();
if ( args.Length == 1 )
form.OpenDocument(args[0]); // OpenDocument calls docManager.OpenDocument
Application.Run(form);
}
*/
编写一个界面,实现了另存和读取。

如果需要同时保存多种状态的话,就可以使用结构体。比如这个结构体:
同时将保存和读取的代码贴出来。
private void docManager_LoadEvent(object sender, SerializationEventArgs e)
{
try
{
StreamStruct streamStruct = new StreamStruct();
streamStruct = (StreamStruct)e.Formatter.Deserialize(e.SerializationStream);
pictureBox1.Image = streamStruct.bmp;
textBox1.Text = streamStruct.str;
}
catch { }
mruManager.Add(e.FileName);
}
private void docManager_SaveEvent(object sender, SerializationEventArgs e)
{
// DocManager asks to save document to supplied stream
try
{
StreamStruct streamStruct = new StreamStruct();
streamStruct.str = textBox1.Text;
streamStruct.bmp = (Bitmap) pictureBox1.Image;
List<List<Rectangle>> llr = new List<List<Rectangle>>();
for(int index = 0;index<70;index++)
{
List<Rectangle> innerList = new List<Rectangle>();
for (int innerIndex = 0; innerIndex < 4; innerIndex++)
innerList.Add(new Rectangle(0, 0, 0, 0));
llr.Add(innerList);
}
streamStruct.llr = llr;
e.Formatter.Serialize(e.SerializationStream, streamStruct);
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}