如何自动保存和恢复窗体的大小,位置等等的信息

类别:.NET开发 点击:0 评论:0 推荐:

 

内容提要(译者)

这篇文章中,给我们介绍了一个可以自动保存窗体状态信息的一个类,这个类可以从他的父窗体中预订事件,自动保存和恢复窗体的状态.实现方法可以说是非常的巧妙,并且非常的通用.

文章中的代码可以从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;
 
        // 在设置注册表的HKEY_CURRENT_USER中设置路径
        m_windowState.RegistryPath = @"Software\YourCompany\YourApp"; 
    }
 
    [STAThread]
    static void Main() 
    {
        Application.Run(new AppForm());
    }
}

 

上面就是如何能自动的保存和取出窗体的状态的所有的代码,非常短小精悍。我还在PersistWindowState类中添加了其它的一些功能,它可以自动的保存和取出另外的一些信息。窗体添加了两个事件PersistWindowState.LoadStateEventPersistWindowState.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;
 
        // HKEY_CURRENT_USER 设置注册表的路径 
        m_windowState.RegistryPath = @"Software\YourCompany\YourApp"; 
        
        // 添加load and save 事件
        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.ClosingForm.Load中完成的.我第一次用 .Net Beta 1版本来实现这个功能的时候,我发现在Form.Load恢复保存的信息的时候,会使窗体的visiable属性变化,但是在正式版中再没有发现这个问题.

 

下面是实现PersistWindowState类的所有代码:

 

public class PersistWindowState : System.ComponentModel.Component
{
    // event info that allows form to persist extra window state data
// 这是保存和恢复窗体状态的事件
    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);
        
        // 触发 SaveState 事件
        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;
 
            // 触发LoadState事件
            if(LoadStateEvent != null)
                LoadStateEvent(this, key);
        }
    }
}

 

你是否注意到有这个属性AllowSaveMinimized,如果这个属性被设置为true,如果窗体在最小化时被关闭,当恢复的时候,它也是最小化. 这也许不是你所要的,所有我们把这个属性缺省设置为false.

 

最后,我希望会有人能觉得这个类还比较有用,会有人能从中得到一些的启示.

 

 

本文地址:http://com.8s8s.com/it/it45916.htm