■ はじめに
* Windowsアプリの状態(ウインドウ位置, サイズ etc)を復元する仕組みを調べてみた。
使い道
例えば、以下の関連記事のアプリ「画像比較スライダー」の状態(境界線の位置)を 保持しておきたい時などに使用。詳細は、以下の関連記事を参照。Splitter ~ 画像比較スライダーをWindows Formで実装する ~
https://blogs.yahoo.co.jp/dk521123/37846450.html
設定ファイルの保存については、以下の関連記事を参照。アプリの設定ファイル
https://blogs.yahoo.co.jp/dk521123/38122457.html
■ サンプル
例1:Hello World
手順[1] ソリューションエクスプローラ内のプロジェクト名を右クリックして、 [プロパティ]-[設定]を選択する 名前 種類 スコープ 値 HelloWorld string ユーザー ※ 名前「HelloWorld」は、キーとなる値 => 「C:\Users\【アカウント名】\AppData\Local\【アプリ名】\【ランダム?文字列】\user.config」にXML形式で保存されるコントロール構成
* button x 2 * Textbox x 1コード
using System; using System.Windows.Forms; namespace SampleForm { public partial class Form1 : Form { public Form1() { InitializeComponent(); } // 保存処理 private void button1_Click(object sender, EventArgs e) { Properties.Settings.Default.HelloWorld = this.textBox1.Text; Properties.Settings.Default.Save(); } // 復元処理 private void button2_Click(object sender, EventArgs e) { this.textBox1.Text = Properties.Settings.Default.HelloWorld; } } }
例2:アプリ状態をクローズで保存、ロードで復元
* 以下のアプリ状態をクローズで保存、ロードで復元 [1] ウインドウステート(Normal、最小化、最大化) [2] ウインドウの位置 [3] ウインドウの大きさ手順
[1] ソリューションエクスプローラ内のプロジェクト名を右クリックして、 [プロパティ]-[設定]を選択する ※「種類」(データ型)を選択するには、「参照」から選んでいく 名前 種類 スコープ 値 FormState System.Windows.Forms.FormWindowState ユーザー Normal FormLocation System.Drawing.Point ユーザー 0, 0 FormSize System.Drawing.Size ユーザー 0, 0コード
using System.Windows.Forms; namespace SampleForm { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, System.EventArgs e) { if (Properties.Settings.Default.FormSize.IsEmpty) { // 初回起動時は復元処理は行わない return; } // [1] ウインドウステート(Normal、最小化、最大化) if (Properties.Settings.Default.FormState == FormWindowState.Minimized) { this.WindowState = FormWindowState.Normal; } else { this.WindowState = Properties.Settings.Default.FormState; } // [2] ウインドウの位置 this.Location = Properties.Settings.Default.FormLocation; // [3] ウインドウの大きさ this.Size = Properties.Settings.Default.FormSize; } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { // [1] ウインドウステート(Normal、最小化、最大化) Properties.Settings.Default.FormState = this.WindowState; if (this.WindowState == FormWindowState.Normal) { // ウインドウステート = Normalの場合 // [2] ウインドウの位置 Properties.Settings.Default.FormLocation = this.Location; // [3] ウインドウの大きさ Properties.Settings.Default.FormSize = this.Size; } else { // ウインドウステート = 最小化/最大化の場合、RestoreBoundsを保存 // [2] ウインドウの位置 Properties.Settings.Default.FormLocation = this.RestoreBounds.Location; // [3] ウインドウの大きさ Properties.Settings.Default.FormSize = this.RestoreBounds.Size; } Properties.Settings.Default.Save(); } } }
■ 補足:ウインドウの位置を保持する場合
http://blog.ahh.jp/?p=1360で記載されているが、以下の「考慮しないといけないケース」だと 復元前に、モニター内に含まれているかを判定する
考慮しないといけないケース
イレギュラーなケースかもしれないが...[1] マルチモニターで、メインではなく、サブモニター内にフォームを保存 [2] [1]のPCからサブモニターを抜き、メイン画面だけにする
サンプル
var targetArea = new Rectangle( Properties.Settings.Default.FormLocation.X, Properties.Settings.Default.FormLocation.Y, Properties.Settings.Default.FormSize.Width, Properties.Settings.Default.FormSize.Height); // モニター外に出ていないか調査 foreach (var screen in Screen.AllScreens) { // モニター内にフォームが重なるか判定する if (screen.WorkingArea.IntersectsWith(targetArea)) // モニター内にフォームに含まれているか判定する //if (screen.WorkingArea.Contains(targetArea)) { this.Location = Properties.Settings.Default.FormLocation; this.Size = Properties.Settings.Default.FormSize; break; } }
補足:Rectangle.Contains/IntersectsWith について
図形 ~ 矩形 / Rectangle ~https://blogs.yahoo.co.jp/dk521123/37888274.html
参考文献
まずは、仕組みを知る上で一読しておくといいかもhttps://qiita.com/taigaaa2/items/7f05ad950a57033892ae
本格的にアプリに組み込むために参考になる
https://www.wareko.jp/blog/c-sharp-form-application-save-restore-window-state-position-size
その他
https://qiita.com/nicklegr/items/faefb804697a395b148d
http://www.atmarkit.co.jp/fdotnet/dotnettips/438winsettings/winsettings.html
関連記事
Windows Form
Windows Form ~ 目次 ~https://blogs.yahoo.co.jp/dk521123/8054245.html
アプリの設定ファイル
https://blogs.yahoo.co.jp/dk521123/38122457.html
Splitter ~ 画像比較スライダーをWindows Formで実装する ~
https://blogs.yahoo.co.jp/dk521123/37846450.html
その他
図形 ~ 矩形 / Rectangle ~https://blogs.yahoo.co.jp/dk521123/37888274.html