かくすけのいろいろ作るブログ

かくすけの開発者ブログです。開発の他いろいろなモノづくりについて書きます。

【C#】JSONテキストとして設定値を保持する

Visual Studio 2019
C#

こんにちは。かくすけです。
前回まではOCR関連の記事を書いていましたがそこはいったん置いといて、今回は設定した翻訳範囲の保持をできるようにしていきます。

開発中のシステム説明記事はこちら
kakusuke98.hatenablog.com

現時点で

  • 翻訳範囲指定
  • 文字認識
  • 翻訳
  • 翻訳結果表示

の一連の流れはできるようになっています。
ただし、いまは一度アプリを終了してしまうと指定した翻訳範囲は初期化されてしまうため、起動するたびに翻訳範囲を指定する必要があります。
ちょっとした手間ですね。今回はこのちょっとした手間を省けるよう、指定した翻訳範囲をアプリ再起動時にも指定したままにできるような仕組みを作っていきます。

目次

  • 概要
  • 設定値の読み込み・書き込み
  • JSONテキスト⇔オブジェクトの変換
  • 実際の動作

概要

翻訳範囲を変更したタイミングで設定値を保存し、起動時にはその値を読み込むようにします。

  1. アプリ起動
  2. 設定値取得
  3. JSONテキスト⇒クラスオブジェクト変換
  4. 翻訳動作など
  5. クラスオブジェクト⇒JSONテキスト変換
  6. JSONテキストを設定値として保存
  7. アプリ停止

という流れになります。

↓のページで紹介されているようにC#JSONを扱うにはいくつか方法があります。
dev.classmethod.jp

シンプルで軽量という理由でDynamicJsonを使おうかと思い、試してみたのですが私がJSONにしたいオブジェクトが複雑すぎてだめっぽかったのでDataContractJsonSerializerを使うことにしました。

設定値の読み込み・書き込み

次のページの通り、Visual Studio 2005 以降であればデフォルトで設定値保存機能があるようです。
dobon.net

こちらの方法を使ってアプリを閉じても値を保存できるようにしていきます。
私はVisual Studio 2019 を使用しています。

ページに書いてある通りなのですが、プロジェクト⇒〇〇のプロパティ⇒リソース の順番で選択し、設定一覧画面を表示します。
名前を入力し、データの種類を選択します。JSONテキストは文字列なのでstringを選択しました。
スコープはユーザーにしました。ユーザーにすることで同じPCであってもログインするユーザーが違えば別の設定値を使うことになります。

これで設定値の枠組みが準備できました!
しかし枠組みだけあっても仕方ありません。書き込みと読み込みを行います。
プロジェクト名部分や設定名部分は自分の環境に合わせて読みかえてくださいね。

設定値書き込み

// CaptureTransformApp:プロジェクト名 CaptureSettingSets: 設定名
CaptureTransformApp.Properties.Settings.Default.CaptureSettingSets = 'test';
CaptureTransformApp.Properties.Settings.Default.Save();

これで設定名"CaptureSettingSets"に"test"という文字列が設定できました。
設定値をセットした後はSaveしないと意味がないのでお忘れなく。
複数の設定値をセットしたい場合は複数セットして、最後に1度SaveすればOK。
私はメインウィンドウが閉じられる直前に呼ばれる「MainWindow_FormClosing」メソッドにこの処理を入れています。

設定値読み込み

// CaptureTransformApp:プロジェクト名 CaptureSettingSets: 設定名
CaptureTransformApp.Properties.Settings.Default.Reload();
string load_string= CaptureTransformApp.Properties.Settings.Default.CaptureSettingSets;

これで設定名"CaptureSettingSets"に設定されている値が取得できます。
セット後にSaveが必要なのと同様に、読み込み前にReloadをしましょう。
私はこの処理を起動時に行うようにしています。

JSONテキスト⇔オブジェクトの変換

前項目では"設定値の読み込み・書き込み"を紹介しました。
そこでは"test"という値をセットしていましたが、実際はJSONテキストを設定したいので

  • クラスオブジェクト⇒JSONテキスト変換
  • JSONテキスト⇒クラスオブジェクト変換

の方法を紹介します。

クラスオブジェクト⇒JSONテキスト変換

using System.Runtime.Serialization.Json;  // 最初に読み込む必要あり
...

using (var ms = new MemoryStream())
using (var sr = new StreamReader(ms))
{
    var serializer = new DataContractJsonSerializer(typeof(SetValues));  // SetValues: オリジナルクラス名
    serializer.WriteObject(ms, setValues);  // setValues: JSON変換したいオブジェクト
    ms.Position = 0;

    var json = sr.ReadToEnd();  // jsonにJSONテキストが代入される
}

今回は SetValues というオリジナルクラスのオブジェクトをJSONテキストに変換しています。
ここで変換したJSONテキストを設定値書き込みで書き込んであげれば、複雑なクラスでも設定値を保持することができます!
そしてオリジナルクラスを使う場合は[Serializable]をクラス定義部分の直前に入れてあげる必要があります

こんな感じ。

[Serializable]
internal class SetValues
{
    public List<CaptureSettingSet> CaptureSettingSets;
    // オブジェクト生成
    public SetValues(List<CaptureSettingSet> captureSettingSets)
    {
        CaptureSettingSets = captureSettingSets;
    }
}

また、この例のようにオリジナルクラス内に別のオリジナルクラスが含まれる場合、含まれる方のクラス定義部分にも入れる必要があります。

JSONテキスト⇒クラスオブジェクト変換

// jsonString: JSONテキスト
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
{
    var serializer = new DataContractJsonSerializer(typeof(SetValues)); // SetValues: オリジナルクラス名
    SetValues testObject = (SetValues)serializer.ReadObject(ms); // SetValues: オリジナルクラス名
}

JSONテキスト⇒クラスオブジェクト変換は逆より簡単。
変換後のクラスを指定してあげる必要があるので、例のごとく SetValues の部分は読みかえてくださいね。

実際の動作

今回紹介した方法を使ったシステムのGIF動作です。
f:id:kakusuke98:20200205230308g:plain 「Shift + F2」と設定されていたものを「A」に変更した後、一度アプリを閉じて開きなおしても設定値が「A」のままになっています。

多くの Windows Form App で設定値の保存は必要になると思います。
是非ご活用ください!
そして、他に良い方法をご存知の方は教えていただけると嬉しいです。