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



スポンサーサイト
 

Emacs における矩形領域のコピペ系編集機能

Emacs では矩形領域で切り取り、貼り付けといったことが可能です。 これは結構コーディングなどに便利なので、今回はこの矩形領域の編集機能について紹介したいと思います。
ちなみに MS Word や Visual Studio では Alt + ドラッグで矩形領域を指定できます。

基本機能

基本は矩形で切り取って、貼り付けます。
キー コマンド 機能
C-x r k kill-rectangle 切り取り
C-x r y yank-rectangle 貼り付け

emacs_rect_cut.png
切り取り
emacs_rect_cutted.png
貼り付け
emacs_rect_yank.png

ちなみに VS などと違い、矩形領域で切り取った内容はクリップボード(kill-ring)とは別に記録されます。

その他の矩形処理

切り取り、貼り付け以外にも次のような機能があります。
キー コマンド 機能
C-x r d delete-rectangle 削除(保存しないので、貼り付けはできない)
C-x r c clear-rectangle クリア(空白への置換)
C-x r o open-rectangle 指定領域分の空白を挿入
C-x r t string-rectangle 指定文字への置換
C-x r N rectangle-number-lines ナンバリングする

クリア( C-x r c ) :
emacs_rect_clear_pre.png emacs_rect_clear.png


空白の挿入( C-x r o ) :
emacs_rect_clear_pre.png emacs_rect_open.png


置換( C-x r t ) :
emacs_rect_string_pre.png emacs_rect_string.png
領域内を "|" で置換


ナンバリング( C-x r N ) :
emacs_rect_num_pre.png emacs_rect_num.png

矩形でのコピー

"あれ、コピー忘れてない?" と思った人もいるかもしれません。しかし、忘れたわけではなく、この矩形領域の処理では切り取りはあるのに、なぜかコピーがありません。 理由はよくわかりませんが、切り取った後、Undo すれば、コピーと同じではあります。

読み取り専用バッファー

ただ、そのままだと読み取り専用バッファーでは切り取りができません。 kill-read-only-ok 変数を t(真) に設定すると、読み取り専用の場合にはコピーをするようになります。

変数の設定は M-x customize-option kill-read-only-okCustomizeで設定するか、以下の記述を ~/.emacs.d/init.el に追加して下さい。
(setq kill-read-only-ok t)

矩形のコピー関数の自作

前節の方法でも構わないのですが、 いちいち Undo するのも面倒なので、矩形でのコピーコマンドを自作してみました。

以下の記述を ~/.emacs.d/init.el に追加すると C-x r e で矩形のコピーができるようになります。
(defun my-kill-rectangle-ring-save (start end)
  "Copy the region-rectangle and save it as the last killed one."
  (interactive "r")
  (setq killed-rectangle (extract-rectangle start end))
  (deactivate-mark)
  (message "Copy rectangle region"))
(define-key ctl-x-r-map "e" 'my-kill-rectangle-ring-save)

追記 2013-11-29
レジスターに登録するのであれば、そのままでも矩形のコピーは可能です。


 

Emacs で複数のコピーや位置を保存するレジスターとブックマーク機能

Emacs のレジスター機能を使うとコピーした文字列やカーソル位置をキーを付けて管理することができます。 今回はこのレジスター機能とそれに近いブックマークの機能を合わせて説明します。

文字列のレジスター

通常のクリップボードの処理では M-w で選択領域をコピーして、 C-y でコピーした内容を貼り付ます。 これはよく使う基本的な機能でしょう。ただ、新しい領域をコピーすると前のものが消えてしまうため、前にコピーした内容を使いたいことがあります。こんな時、レジスターを使えば、複数のコピーを管理することができます。

複数の管理を行うには識別するためのキーが必要となります。 レジスターではアルファベット 1 文字(記号も可)がキーです。
コピーするときにアルファベットを割り当て、 貼り付けるときにアルファベットで登録した文字列を指定します。
キー コマンド 機能
C-x r s
C-x r x
copy-to-register 選択範囲をレジスターにコピー
C-x r i
C-x r g
insert-register カーソル位置にレジスターから貼り付け

また、 C-x r r(copy-rectangle-to-register) では矩形領域をコピーすることができます。 貼り付ける際のコマンドは同じです。 矩形領域の処理については以前の記事をご覧ください。 ちなみに文字列のレジスターでは 数字を使った登録機能(C-x r nC-x r +)もあります。 キーマクロと一緒に使うと便利らしいのですが、私は使ったことがありません。


なお、最初のコピーの話を少し補足すると、 Emacs ではコピーした内容は kill-ring に追加されていくので、正確には消えたわけではありません。 M-y で過去にコピーした文字列を張り付けることも可能です。

カーソル位置のレジスター

レジスターではバッファー上のカーソル位置も登録することができます。 こちらも同様にアルファベットをキーとして登録し、アルファベットを指定して登録位置にジャンプします。
キー コマンド 機能
C-x r [Space]
C-x r [C-Space]
C-x r C-@
point-to-register カーソル位置をレジスターに登録
C-x r j jump-to-register レジスターの登録位置へジャンプ

また、 カーソル位置だけでなく、その場のウィンドウやフレームの状態も含めて保存しておくこともできます。 ジャンプ(復元)の際のコマンドは変わりません。
キー コマンド 機能
C-x r w window-configuration-to-register ウィンドウ状態をレジスターに登録
C-x r f frame-configuration-to-register フレーム状態をレジスターに登録

ブックマーク

レジスターによるカーソル位置の登録では、 Emacs を終了すると忘れてしまいます。

こんなときにはブックマークを使います。
ブックマークでは登録内容をファイル(~/.emacs.d/bookmarks)に保存するので、次に起動した場合も有効です。 また、キーはアルファベット 1 文字ではなく、名前(文字列)となっています。
キー コマンド 機能
C-x r m bookmark-set カーソル位置をブックマークに保存
C-x r b bookmark-jump ブックマーク位置へジャンプ
C-x r l bookmark-bmenu-list 登録済みブックマークの一覧表示

登録したブックマークを削除したい場合にはブックマークの一覧から行います。 一覧は Dired などの一般的なリストの操作と同じです。 (d でマークして、 x で実行)



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

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

10月 | 2013年11月 | 12月
- - - - - 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


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

yohshiy

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

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

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