Settings を使った WPF でのアプリケーション設定の保存 (ウィンドウの表示位置、サイズの保存)

.NET ではアプリケーションの設定を保存する際に Settings という機能を使用します。 今回はこの Settings の使い方を説明したいと思います。
説明のサンプルはウィンドウの表示位置、サイズの保存にしています。


Settings の使い方としては次の 2 つの方法があります。
  1. コードから利用
  2. XAML のリソースとして利用
ただし、XAML のリソースとして使う場合も初期値として使うだけで、 終了時の保存はコードから行う必要があります。

Settings について

先に Settings について少し説明しておきます。

Windows における設定ファイルの変遷

Windows の初期の頃では INI ファイル というテキストファイルを使ってアプリケーションの設定を保存していました。
ただ、この INI ファイルは実行ファイルと同じところに保存しておくことが多く、 1 つの PC を複数で使うマルチユーザー環境では使いづらいところがありました。

MFC の頃になるとレジストリがよく使われるようになりました。
これはマルチユーザーにも対応しています。しかし、アンインストールがちゃんとできないとゴミが残りますし、手動で修正する場合には "自己責任で行って下さい" という恐ろしい文言がついて回ります。また、実際に間違ったものを消すと非常に危険でもありました。

.NET からは XML ファイルで設定を保存する方法が採用され、 これを利用するため機能が Settings です。

スコープ

Settings ではアプリケーションユーザーの 2 つのスコープがあります。
マルチユーザー環境では、アプリケーションの設定はユーザーごとに保存する必要があります。 このため基本的にユーザースコープを使用します。

アプリケーションスコープの場合はアプリケーションで共通の設定となります。
こちらはコードの変更なしで客先ごとに設定を変えたり、インストーラーで設定を変えたりといった場合に使用します。 このため、アプリのプログラム内からはアプリケーションスコープの値は通常読み取りのみで、 変更はしません。

今回はアプリの設定の保存なので、ユーザースコープのみ説明します。
アプリケーションスコープについて知りたい場合は、以下のサイトなどが参考になるのではないかと思います。

設定ファイルの保存場所

ユーザーの設定を保存する XML ファイルは以下の名前で作成されます。 ここでの Company 等の名前は Properties/AssemblyInfo.cs で指定された値です。
(ユーザーフォルダー)\AppData\Local\CompanyName\ProgramName_xxxx\Version\user.config
Settings の設定値は app.config というファイルに記述されます。 これがビルド時に "実行ファイル名.config" という名前でコピーされて、実行ファイルと同じ場所に置かれます。
初回起動時でユーザーの設定ファイルがない場合には、 そのファイルの値がデフォルト値として使用されます。

使い方(コードからの利用)

ここから、実際にサンプルを作りながら、使い方を説明していきます。
サンプルは終了時のウィンドウの表示位置とサイズを保存して、次回起動時にその位置とサイズで表示するだけのプログラムです。

まず "SettingsSample" という名前で [WPF アプリケーション] を新規作成します。 構成は次のようになっています。
wpf_settings_proj.png

Settings の記述

Settings.settings のファイルを開き、ここに保存したい変数を追加します。
保存する値は MainWindow の表示位置とサイズです。デフォルト値は適当に指定しておきます。
  • サイズ(Width, Height)
  • 表示位置(Left, Top)
wpf_settings_edit.png

ここでアクセス修飾子[Public] に変更します。 Public にしておくと、以下の記述によりコード上で Settings の値にアクセスできるようになります。
 Properties.Settings.Default.名前 
Settings.settings を編集すると app.config ファイルが追加されます。

起動時のロード

MainWindow のコンストラクターまたは Loaded イベントのコールバックで Settings の値を MainWindows のプロパティに設定します。 ここではコンストラクターで行うことにします。

MainWindow.xaml.cs :
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // Settings の値をウィンドウに反映
        Left   = Properties.Settings.Default.MainWindow_Left;
        Top    = Properties.Settings.Default.MainWindow_Top;
        Width  = Properties.Settings.Default.MainWindow_Width;
        Height = Properties.Settings.Default.MainWindow_Height;
    }
}
ここでビルドして実行してみてください。 Settings に記述したデフォルト値でウィンドウが表示されると思います。

終了時の保存

終了時の状態を保存するためには Closing イベントのコールバックで保存用のコードを追加します。 MainWindow の [プロパティ] を表示し、 Closing イベントのところでダブルクリックしてコールバック Window_Closing() を追加します。
wpf_settings_closing.png


Window_Closing() に以下のコードを記述すると、終了時の値が保存されるようになります。
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    if (WindowState == WindowState.Normal)
    {
        // ウィンドウの値を Settings に格納
        Properties.Settings.Default.MainWindow_Left   = Left;
        Properties.Settings.Default.MainWindow_Top    = Top;
        Properties.Settings.Default.MainWindow_Width  = Width;
        Properties.Settings.Default.MainWindow_Height = Height;
        // ファイルに保存
        Properties.Settings.Default.Save();
    }
}
ポイントは最後の Properties.Settings.Default.Save() メソッドを実行している点です。
Settings では、設定ファイルからのロードは自動的に行われるのですが、 保存は Save() メソッドで明示的に行う必要があります。

また、 Window の状態をチェックしているのは、最小化している場合にサイズ等を保存しないようにしているためです。最大化、最小化の状態も保存したい場合は WindowState の状態も保存する必要があります。


ちなみに MSDN によれば、ウィンドウの位置、サイズの保存は WINDOWPLACEMENT 構造体を使っています。 ただ、それだとちょっとめんどくさかったので、今回は使っていません。 サンプルのコードは次のサイトを参考にさせていただき、 WPF 用に書き直したものです。

使い方(XAML からの利用)

Settings の値は文字列リソース(Resources.resx)と同様に XAML のリソースとして直接指定することもできます。 Resources.resx の場合と違い、直接使ってもリビルドした際の実行時例外は発生しません。 こちらの方法もサンプルを作って説明していきます。
まず、前章と同様にプロジェクトを作成し、 Settings.settings の編集を行って下さい。

リリースファイルの登録

リソースファイルを使えるようにするためには、 App.xaml にリソースを登録する記述を追加します。

App.xaml :
 <Application x:Class="SettingsSample.App"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:prop="clr-namespace:SettingsSample.Properties"
              StartupUri="MainWindow.xaml">
     <Application.Resources>
         <prop:Settings x:Key="sett" />
     </Application.Resources>
 </Application>

UI からのリソース利用

MainWindow の [プロパティ] で Top, Left, Width, Height のそれぞれに対して、 Settings の値をリソースとしてバインドします。

各項目のところでデータバインドを設定するダイアログを開きます。

wpf_settings_res_menu.png

[ソース] で [StaticResource] → [Application.Resources] → [sett] と順に選択してから、 [パス] で Settings の名前を選択します。

wpf_settings_res_source.png wpf_settings_res_path.png

コードの記述

起動時の設定は XAML で記述したので、コードには記述しません。
ただし、XAML の記述では StaticResource として指定しているため、 データバインドのモードを "TwoWay" に変えたとしても、 Settings の値は変更されません。 終了時の値の保存はコード上で行う必要があります。


MainWindow.xaml.cs :
public MainWindow()
{
    InitializeComponent();
}

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    if (WindowState == WindowState.Normal)
    {
        // ウィンドウの値を Settings に格納
        Properties.Settings.Default.MainWindow_Left   = Left;
        Properties.Settings.Default.MainWindow_Top    = Top;
        Properties.Settings.Default.MainWindow_Width  = Width;
        Properties.Settings.Default.MainWindow_Height = Height;
        // ファイルに保存
        Properties.Settings.Default.Save();
    }
}

サンプルコード

サンプルとして使ったプログラムの全コードもあげておきます。
サンプル Browse Download
コード版 SettingsSample_code SettingsSample_code.zip
リソース版 SettingsSample SettingsSample.zip



関連記事
スポンサーサイト
Prev.    Category    Next 

Facebook コメント


コメント

コメントの投稿

Font & Icon
非公開コメント

このページをシェア
アクセスカウンター
アクセスランキング
[ジャンルランキング]
コンピュータ
39位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
4位
アクセスランキングを見る>>
カレンダー(アーカイブ)
プルダウン 降順 昇順 年別

04月 | 2017年05月 | 06月
- 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 - - -


はてな新着記事
はてな人気記事
ブロとも申請フォーム
プロフィール

yohshiy

Author:yohshiy
職業プログラマー。
仕事は主に C++ ですが、軽い言語マニアなので、色々使っています。

はてブ:yohshiy のブックマーク
Twitter:@yohshiy

サイト紹介
プログラミング好きのブログです。プログラミング関連の話題や公開ソフトの開発記などを雑多に書いてます。ただ、たまに英語やネット系の話になることも。