12
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Windows GUIプログラミング入門11 設定保存(2)

Last updated at Posted at 2017-03-27

■はじめに

今回はexeと同じ場所に独自の設定ファイルを作成するタイプのプログラムを作ります。
このタイプはProgram Files配下へのインストール禁止です。
Program Files配下は設定ファイルやログなど、インストール後に更新するファイルを置いてはいけません。

キーワード:シングルユーザー設定, JSON, JavaScriptSerializer, Calendar

[注意]
これまでの回で説明済みの操作方法等は、説明を省略したり簡略化している場合があります。

■開発環境

  • Windows 10
  • Visual Studio Community 2017
  • .NET Framework 4.x

■作ってみる

画面の入力内容をexeと同じ場所にjsonファイルとして保存するプログラムを作ります。
ログインユーザー毎に設定を持つほどではない、小さなツールなどに向いています。

◇コントロールの配置、プロパティ設定

TextBoxを3つ、Calendarを1つ配置します。
wbg11-01.png

4つのコントロールのNameプロパティ、TextBoxTextプロパティを更新します。
wbg11-02.png

◇データ型追加

プロジェクトにクラスを追加します。
名前はPerson.csにします。

Person.cs
using System;

namespace WpfApp11
{
    /// <summary>
    /// 人クラス
    /// </summary>
    public class Person
    {
        /// <summary>
        /// 名前
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 歳
        /// </summary>
        public int Age { get; set; }

        /// <summary>
        /// 誕生日
        /// </summary>
        public DateTime Birthday { get; set; }
    }
}

◇参照設定の追加

「参照」の右クリックメニューから「参照の追加」を選択します。
wbg11-03.png

JavaScriptSerializerを使うためにSystem.Web.Extensionsを追加します。
wbg11-04.png

◇設定読み書きクラス追加

プロジェクトにもう1つクラスを追加します。
名前はConfig.csにします。
PersonプロパティとMemoプロパティが画面の項目と対応します。

Config.cs
using System.IO;
using System.Text;

namespace WpfApp11
{
    /// <summary>
    /// 設定クラス
    /// </summary>
    public class Config
    {
        #region フィールド定義

        /// <summary>
        /// 人
        /// </summary>
        public Person Person { get; set; }

        /// <summary>
        /// メモ
        /// </summary>
        public string Memo { get; set; }
        
        #endregion

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public Config()
        {
            this.Person = new Person();
        }

        /// <summary>
        /// 設定ファイルのフルパスを取得
        /// </summary>
        /// <returns>設定ファイルのフルパス</returns>
        public static string GetConfigFilePath()
        {
            // 実行ファイルのフルパスを取得
            string appFilePath = System.Reflection.Assembly.GetEntryAssembly().Location;

            // 実行ファイルのフルパス末尾(拡張子)を変えて返す
            return System.Text.RegularExpressions.Regex.Replace(
                appFilePath,
                ".exe",
                ".json",
                System.Text.RegularExpressions.RegexOptions.IgnoreCase);
        }

        /// <summary>
        /// 設定読み込み
        /// </summary>
        /// <returns></returns>
        public static Config ReadConfig()
        {
            // 設定ファイルのフルパスを取得
            string configFile = GetConfigFilePath();

            if (File.Exists(configFile) == false)
            {
                // 設定ファイルなし
                return null;
            }

            using (var reader = new StreamReader(configFile, Encoding.UTF8))
            {
                // 設定ファイル読み込み
                string buf = reader.ReadToEnd();

                // デシリアライズして返す
                var js = new System.Web.Script.Serialization.JavaScriptSerializer();
                return js.Deserialize<Config>(buf);
            }
        }

        /// <summary>
        /// 設定書き込み
        /// </summary>
        /// <param name="cfg"></param>
        public static void WriteConfig(Config cfg)
        {
            // シリアライズ
            var js = new System.Web.Script.Serialization.JavaScriptSerializer();
            string buf = js.Serialize(cfg);

            // 設定ファイルのフルパス取得
            string configFile = GetConfigFilePath();

            using (var writer = new StreamWriter(configFile, false, Encoding.UTF8))
            {
                // 設定ファイルに書き込む
                writer.Write(buf);
            }
        }

    }
}

◇設定読み込み、保存処理作成

コードビハインドに、設定ファイルを読み込んで画面に反映する処理を追加します。

MainWindow.xaml.cs
/// <summary>
/// 設定読み込み、画面に反映
/// </summary>
private void LoadFromConfig()
{
    // 設定ファイルから読み込み
    var cfg = Config.ReadConfig();
    if (cfg == null)
    {
        // 設定ファイルなし
        return;
    }

    // 画面に反映
    nameText.Text = cfg.Person.Name;
    ageText.Text = cfg.Person.Age.ToString();
    cal.SelectedDate = cfg.Person.Birthday.ToLocalTime();
    memoText.Text = cfg.Memo;
}

コードビハインドに、画面内容を設定ファイルに保存する処理を追加します。

/// <summary>
/// 画面の内容を設定保存
/// </summary>
private void SaveToConfig()
{
    var cfg = new Config();

    cfg.Person.Name = nameText.Text;
    int age;
    if (int.TryParse(ageText.Text, out age) == false)
    {
        // 数値に変換できなかったら0にしておく
        age = 0;
    }
    cfg.Person.Age = age;
    cfg.Person.Birthday = (DateTime)cal.SelectedDate;
    cfg.Memo = memoText.Text;

    // 画面内容を設定ファイルに保存
    Config.WriteConfig(cfg);
}

Windowの起動時に設定読み込み処理を呼ぶようにします。

/// <summary>
/// ウィンドウのコンテンツレンダリング後
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Window_ContentRendered(object sender, EventArgs e)
{
    // 設定読み込み
    LoadFromConfig();
}

Window終了時に設定を保存する処理を呼ぶようにします。

/// <summary>
/// ウィンドウ閉じる時
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Window_Closed(object sender, EventArgs e)
{
    // 設定保存
    SaveToConfig();
}

■動かしてみる

Releaseビルドし、exeを起動してみます。
wbg11-05.png

TextBoxの内容を変更し、Calendarの日付を選択し、×ボタンで画面を閉じます。
wbg11-06.png

jsonファイルが作成されました。
wbg11-07.png

jsonファイルをテキストエディタで開いてみます。
wbg11-08.png

再度exeを起動してみます。きちんと入力値が復元されました。
wbg11-09.png

■別の設定ファイル形式

jsonではなく、TOML形式を使う場合は こちら

おしまい


<< 最初の記事   < 前の記事   次の記事 >

12
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?