内容提要(译者)
这篇文章中,给我们介绍了一个可以自动保存窗体状态信息的一个类,这个类可以从他的父窗体中预订事件,自动保存和恢复窗体的状态.实现方法可以说是非常的巧妙,并且非常的通用.
文章中的代码可以从http://www.codeproject.com/csharp/RestoreFormState/RestoreFormState_src.zip下载.
简介
每次我生成一个新的桌面型程序的时候,我都要在主窗口的关闭事件中写一些代码来保存我主窗口一些信息,比如位置,大小,窗体状态等等,这篇文章中,我们讲述了如何使用一个简单的C#类自动完成上面的这些工作. 我在设计这个类的时候,我就考虑到要在使用时候用最少的代码就可以把这个类加到窗体中,并且能够从工具箱中把它加到窗体中.
类是如何工作的
类的名字为PersitWindowState , 为了能更明白理解它的作用,我们先略过它的实现,先来看看它的应用。这个类用起来的非常简单。下面是一个演说如何把它加到一个窗体中:
public class AppForm : System.Windows.Forms.Form { private PersistWindowState m_windowState; public AppForm() { m_windowState = new PersistWindowState(); m_windowState.Parent = this; m_windowState.RegistryPath = @"Software\YourCompany\YourApp"; } [STAThread] static void Main() { Application.Run(new AppForm()); } }
上面就是如何能自动的保存和取出窗体的状态的所有的代码,非常短小精悍。我还在PersistWindowState类中添加了其它的一些功能,它可以自动的保存和取出另外的一些信息。窗体添加了两个事件PersistWindowState.LoadStateEvent 和PersistWindowState.SaveWindowState .这两个事件发生是,有一个RegistryKey 变量,可以在在当注册表中保存和取出窗体一些信息。下面的代码演示了如何使用这个类的这些功能
public class AppForm : System.Windows.Forms.Form { private PersistWindowState m_windowState; public AppForm() { this.Text = "RestoreFormState"; m_windowState = new PersistWindowState(); m_windowState.Parent = this; m_windowState.RegistryPath = @"Software\YourCompany\YourApp"; m_windowState.LoadStateEvent += new PersistWindowState.WindowStateDelegate(LoadState); m_windowState.SaveStateEvent += new PersistWindowState.WindowStateDelegate(SaveState); } private int m_data = 34; private void LoadState(object sender, RegistryKey key) { m_data = (int)key.GetValue("m_data", m_data); } private void SaveState(object sender, RegistryKey key) { key.SetValue("m_data", m_data); } [STAThread] static void Main() { Application.Run(new AppForm()); } }
类是如何实现的
在看完了类PersistWindowState 的各种用法之后,让我们来看看这个类本身的设计. PersistWindowState 的关键就是可以预订其他类的事件. 这个类有4个事件,它们是Form.Closing, Control.Resize, Control.Move 和 Form.Load. 当控件的Parent 属性设置以后,就可以从Parent 中预订这四个事件了(记住, Parent 在这儿是非常有用的属性.)
窗体的状态变化会在 Control.Resize 和 Control.Move 中被记录. Control.Resize 允许我们记录当前窗体的宽度和高度,我们只有在窗体是正常状态(不是最大化也不是最小化)是才会记录这些信息,当窗体是最大化或者是最小化的时候,我们并不记录这些信息. Control.Move 是用来记录窗体的位置(和上面一样,窗体在最小化或者最大化时候,也不作记录)和当前的状态,
保持和取出保存信息是在Form.Closing 和Form.Load 中完成的 . 当我第一次用 .Net Beta 1版本来实现这个功能的时候,我发现在Form.Load 中恢复保存的信息的时候,会使窗体的visiable属性变化,但是在正式版中再没有发现这个问题.
下面是实现PersistWindowState 类的所有代码:
public class PersistWindowState : System.ComponentModel.Component { 这是保存和恢复窗体状态的事件 public delegate void WindowStateDelegate(object sender, RegistryKey key); public event WindowStateDelegate LoadStateEvent; public event WindowStateDelegate SaveStateEvent; private Form m_parent; private string m_regPath; private int m_normalLeft; private int m_normalTop; private int m_normalWidth; private int m_normalHeight; private FormWindowState m_windowState; private bool m_allowSaveMinimized = false; public PersistWindowState() { } public Form Parent { set { m_parent = value; m_parent.Closing += new System.ComponentModel.CancelEventHandler(OnClosing); m_parent.Resize += new System.EventHandler(OnResize); m_parent.Move += new System.EventHandler(OnMove); m_parent.Load += new System.EventHandler(OnLoad); m_normalWidth = m_parent.Width; m_normalHeight = m_parent.Height; } get { return m_parent; } } public string RegistryPath { set { m_regPath = value; } get { return m_regPath; } } public bool AllowSaveMinimized { set { m_allowSaveMinimized = value; } } private void OnResize(object sender, System.EventArgs e) { if(m_parent.WindowState == FormWindowState.Normal) { m_normalWidth = m_parent.Width; m_normalHeight = m_parent.Height; } } private void OnMove(object sender, System.EventArgs e) { if(m_parent.WindowState == FormWindowState.Normal) { m_normalLeft = m_parent.Left; m_normalTop = m_parent.Top; } m_windowState = m_parent.WindowState; } private void OnClosing(object sender, System.ComponentModel.CancelEventArgs e) { RegistryKey key = Registry.CurrentUser.CreateSubKey(m_regPath); key.SetValue("Left", m_normalLeft); key.SetValue("Top", m_normalTop); key.SetValue("Width", m_normalWidth); key.SetValue("Height", m_normalHeight); if(!m_allowSaveMinimized) { if(m_windowState == FormWindowState.Minimized) m_windowState = FormWindowState.Normal; } key.SetValue("WindowState", (int)m_windowState); if(SaveStateEvent != null) SaveStateEvent(this, key); } private void OnLoad(object sender, System.EventArgs e) { RegistryKey key = Registry.CurrentUser.OpenSubKey(m_regPath); if(key != null) { int left = (int)key.GetValue("Left", m_parent.Left); int top = (int)key.GetValue("Top", m_parent.Top); int width = (int)key.GetValue("Width", m_parent.Width); int height = (int)key.GetValue("Height", m_parent.Height); FormWindowState windowState = (FormWindowState)key.GetValue("WindowState", (int)m_parent.WindowState); m_parent.Location = new Point(left, top); m_parent.Size = new Size(width, height); m_parent.WindowState = windowState; if(LoadStateEvent != null) LoadStateEvent(this, key); } } }
你是否注意到有这个属性AllowSaveMinimized ,如果这个属性被设置为true,如果窗体在最小化时被关闭,当恢复的时候,它也是最小化. 这也许不是你所要的,所有我们把这个属性缺省设置为false.
最后,我希望会有人能觉得这个类还比较有用,会有人能从中得到一些的启示.

|