保存和恢复窗体的大小及位置

585 阅读4分钟

有一件让我很烦恼的事情 —— 可能对你来说也一样 —— 设置五个左右的窗口,摆放在桌面上的正确位置,且很可爱。然后你明天再打开它们……其中的某个总是在打开后显示的太大,而且位于屏幕中间……

介绍

保存和恢复窗体的大小及位置真的不难 —— 只需要几行代码 —— 但却也很容易忘记,它确实对你的应用程序外观的“专业”产生影响。如果试图整理桌面上的各个任务,但又经常因为必须移动应用程序到它们所属的位置而导致整理被打乱,这必将使用户感到沮丧......

那么,如果它很简单,为什么不去实现呢?

使用代码

你需要做的只有三件事:

  1. 创建一个保存大小和位置信息的地方
  2. 在启动时恢复信息
  3. 关闭时保存信息

保存位置和大小信息的地方

保存这些信息最简单的地方是应用程序配置文件:

  • 在 Visual Studio 中,打开解决方案资源管理器中的项目分支。
  • 打开“Properties”子分支,双击“Settings.Settings”节点。
  • 将会打开项目的 Settings 页。添加新的条目:“InitialLocation” —— 保持“string”类型和“用户(User)”范围(你也可以输入“Value”,不过真的不需要)。

  • 保存和关闭页面。

恢复位置和大小

这也很容易做到 —— 你需要做的仅仅是设置 Form 的属性,否则打开时的显示看起来会有点乱。在 Visual Studio 设计器中,将 Form 的 StartPosition 设置为 Manual。如果忘记了这一点,Windows会在它认为合适的位置定位窗体,然后再移动到你选择的位置。

译者注:StartPosition 属性也可以直接到窗体的构造函数中设置,如下所示。

public Form1()
{
    InitializeComponent();
    this.StartPosition = FormStartPosition.Manual;
    // this.Location = new Point(0, 0); // Location设置位置,下面会在 Load 事件中处理
}

然后需要做的就是恢复的代码。在 Form.Load 事件中处理:

private void frmMain_Load(object sender, EventArgs e)
{
    if ((ModifierKeys & Keys.Shift) == 0)
    {
        string initLocation = Properties.Settings.Default.InitialLocation;
        Point il = new Point(0, 0);
        Size sz = Size;
        if (!string.IsNullOrWhiteSpace(initLocation))
        {
            string[] parts = initLocation.Split(',');
            if (parts.Length >= 2)
            {
                il = new Point(int.Parse(parts[0]), int.Parse(parts[1]));
            }
            if (parts.Length >= 4)
            {
                sz = new Size(int.Parse(parts[2]), int.Parse(parts[3]));
            }
        }
        Size = sz;
        Location = il;
    }
}

根据条件允许用户进行重新定位:如果用户在打开应用程序时按住 SHIFT 键,它将忽略保存的位置和大小信息,并以设计器中指定的默认大小显示在左上角。如果用户打算完全丢弃保存的信息,这样可以让他们重新覆盖!

代码中都是读取设置,进行基本的检查以确保它们正常,并将其拆分为单独的值。如果有用于位置的值,则进行位置的设置。如果还有用于大小的值,也会进行大小的设置。代码中没有检查确保这些值是整数 —— 假如不是整数,就要由你的程序来负责,因为你保存了错误的信息!

如果没有在“Settings”页面中设置一个“值”,则基本检查将失败,并且应用程序首次运行时不会更改位置和大小 —— 将以设计器中设置的尺寸出现在左上角。

保存位置和大小

剩下的就是在程序关闭时保存信息。同样,这也很简单,在 FormClosing 事件中处理即可:

private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
{
    if ((ModifierKeys & Keys.Shift) == 0)
    {
        Point location = Location;
        Size size = Size;
        if (WindowState != FormWindowState.Normal)
        {
            location = RestoreBounds.Location;
            size = RestoreBounds.Size;
        }
        string initLocation = string.Join(",", location.X, location.Y, size.Width, size.Height);
        Properties.Settings.Default.InitialLocation = initLocation;
        Properties.Settings.Default.Save();
    }
}

同样,也为用户提供了一种跳过的方式,在关闭应用程序时按住 SHIFT 键将不会保存信息。

译注:在 FormClosing 事件中处理几乎是正确的方式,因为只要是点击关闭都会触发 FormClosing 事件。唯一的例外是,最小化时隐藏任务栏中的显示,放到右下角的任务托盘中,其软件退出由任务托盘中的右键菜单实现,此时将不会触发 FormClosing。如果考虑最最严谨的方式,可以考虑 Application.ApplicationExit 事件。

注意点

这样就全部完成了。唯一要记住的是,调试版本和发布版本的应用程序设置文件是不同的 —— 所以,不要指望在切换构建类型时设置会转移!(译注:确切的来说,只要改变应用程序所在路径,设置就会丢失,这是默认的 Settings.settings 的规则)