【Visual Studio】フォルダーの追加方法【WPF】

機能や役割などグループ分けしておいた方がよい場合があります。その場合ファイルを管理する間隔でプロジェクト上にフォルダーを追加する方法があります。

フォルダーの追加

エンティティをまとめておく「Entity」フォルダーを追加してみます。

エンティティについて

ソリューションエクスプローラーでプロジェクト名で右クリックし、「追加」→新しいフォルダーを選択します。

ソリューションエクスプローラーに「NewForlder1」が追加されるので名前を変更します。

「Entity」にフォルダー名を変更しました。

 

Visual Studioでフォルダーを追加すると「Name Space」が定義されます。フォルダー内にクラスを追加するとフォルダー階層が「Name Space」として適用されるためクラス名が重複することを意識する必要がなくなります。

【開発】エンティティオブジェクトの利用【考え方】

今回は、エンティティオブジェクトを利用するということについて書いてみます。

エンティティオブジェクトとは

エンティティオブジェクトはデータの塊を表現するオブジェクト定義です。

Javaではbeanと言われたりします。言語、フレームワークなどの環境で呼ばれ方はいろいろありますが構造はほぼ同じだと思います。

データの塊とは例えばデータベースを利用した場合、テーブルのカラム構成をそのままオブジェクトにした状態となります。

テーブルでの説明

以下のようなユーザーテーブルがあった場合に、エンティティオブジェクトで表現すると。

テーブル定義

No. カラム名(論理名) 備考
1 USER_ID(ユーザー番号) NUMERIC(数値) ユーザーの管理番号
2 USER_NAME(氏名) VARCHAR(文字列) ユーザーの名称
3 STATUS(登録状況) NUMERIC(数値) 0:仮登録、1:本登録
4 UPDATE_DATE(更新日) DATETIME(日時)
5 REGIST_DATE(登録日) DATETIME(日時)

エンティティオブジェクト

No. フィールド名 備考
1 userId int ユーザーの管理番号
2 userName string ユーザーの名称
3 status int 0:仮登録、1:本登録
4 updateDate DateTime
5 registDate DateTime

 


/**
 * ユーザー情報
 */
public class User {
    /**
     * ユーザ番号
     */
    int userId;

    /**
     * ユーザ氏名
     */
    string userName;

    /**
     * 登録状況
     */
    int status;

    /**
     * 更新日時
     */
    DateTime updateDate;

    /**
     * 登録日時
     */
    DateTime registDate;
}

プログラムコードから操作する場合、オブジェクトとしてデータを扱えるとわかりやすいと個人的には思います。
このエンティティオブジェクトを配列にすることでテーブル情報をそのまま扱うことも可能となります。

WEBアプリケーションでの説明

WEBアプリケーションだと、submitを行うとformタグ内のinputタグ、selectタグなどの情報をまとめてWEBサーバーへ送信する仕組みになります。これも、エンティティオブジェクトで取得できるようにするフレームワークがあります。※フレームワークについては、フレームワーク毎のお作法がいろいろと違うため本記事では詳細は割愛させていただきます。

HTML


<html>
<head>
</head>
<body>
  <form>
    <input name="userId" type="hidden" value="2" />
    <input name="userName" type="text" value="涼風青葉" />
    <select name="status">
      <option value="0">仮登録</option>
      <option value="1">本登録</option>
    </select>
    <input type="submit" value="送信" />
  </form>
</body>
</html>

エンティティオブジェクト


/**
 * ユーザー情報
 */
public class User {
    /**
     * ユーザ番号
     */
    int userId;

    /**
     * ユーザ氏名
     */
    string userName;

    /**
     * 登録状況
     */
    int status;
}

フレームワークの仕様にもよりますが、inputタグ、selectタグの名称とエンティティオブジェクトのフィールド名が一致する定義をすることでWEB画面から送信されたデータをエンティティオブジェクトとして受け取ることを実現してくれます。
このような、データベースの情報や画面の入力データなどをプログラムで扱いやすくするオブジェクトをエンティティオブジェクトと理解してます。

【Visual Studio】開発画面構成の覚え書き【WPF】

開発画面の構成についてわかっている範囲で説明します。

※説明に使用している言葉については、いろいろなサイトから流用してはいるのですが自分自身が正式な名称を知らないため間違いがある可能性がありますのでご了承ください。

画面の配置

  1. 編集画面:GUIの操作でコンポーネントの配置などを行うことができます。
  2. ソリューションエクスプローラ:開発に必要なファイルをツリー構造で表示・選択することができます。
  3. XAML(WPFの画面定義):WPFは画面定義をXML形式で管理しております。このXMLを編集する画面になります。(編集画面、プロパティで操作した結果も反映されます。)
  4. プロパティ:編集画面で選択しているコンポーネントの設定を表示・変更できます。

ツールボックス

左側の「ツールボックス」タブをクリックすることでツールボックスが表示されます。

ツールボックスから配置するコンポーネントをドラッグアンドドロップで編集画面へ配置します。

下記画像は「ボタン」をドラッグアンドドロップした状態です。

編集画面とXAMLに反映されます。

 

【Visual Studio】新規プロジェクト作成【WPF】

会社に新入社員が入社してツールの使い方の説明も必要だなと思い、Visual StudioのWPFプロジェクトを作成するまでを書きます。

ダウンロード

まずは、MicrosoftのページからVisual Studioをダウンロードします。

※Microsoft Edgeで実行した画面キャプチャーになります。

https://www.visualstudio.com/ja/downloads/

「保存」を選択します。

ダウンロードを実行した時点でのバージョンは下記の通りでした。

vs_community__481173091.1523791801.exe

インストール

ダウンロードしたファイルを実行します。

起動した画面で「続行」ボタンを押下します。

以下の画面が表示されるので終了するまで待ちます。

以下の画面が表示されたら「インストール」ボタンを押下します。

ワークロードの「.NET デスクトップ開発」を選択し、「場所」にインストール先のフォルダーを指定して、「インストール」ボタンを押下します。

※デフォルトでは「C:\Program Files (x86)\Microsoft Visual Studio\2017\Community」となっているため、特に問題がなければそのままで構いません。

※確認環境ではCドライブにSSDを利用しているため容量の関係でEドライブのHDDへ場所を変更しました。

※WPFプロジェクト作成を行うため「.NET デスクトップ開発」を選択しました。

インストール中は以下の画面が表示されますので終了するまで待ちます。

インストールが完了すると以下の画面が表示されます。

WPFプロジェクト作成

「ファイル」→「新規作成」→「プロジェクト」を選択します。

「WPFプロジェクト」を選択し以下の項目を入力してから「OK」ボタンを押下します。

  • 名前:プログラムの名称になります。
  • 場所:プロジェクトファイルの保存先になります。
  • フレームワーク:.NET frameworkのバージョンを指定します。(通常はデフォルトで問題ございませんが、理由により.NET frameworkのバージョンを変更できない端末で実行する場合に変更します。)
  • ソリューション(※)のディレクトリ作成:チェックしておくとソリューション名のフォルダーが作成されます。

※ソリューションは、複数のプロジェクト(メインプログラム、共通DLL、インストーラーなど)に分けて開発を行う場合にまとめて管理ができるので便利です。

以下の通りWPFプロジェクトが作成されました。

【C#】処理を共通化するという考え方

暗号化・複合化処理を文字列、ファイルを別々にコードを書いているため共通化します。

コードの共通部分を抜き出して共通化しておくことで新規に追加実装する部分は拡張部のみにすることもできます。

今回、共通化するコードは以下のリンク先にある記事で利用したコードの共通部分を抜き出して共通化します。




【C#】ファイルの暗号化・複合化を行う。【AES暗号化】

Encode → EncodeString

Decode → DecodeString

 

【C#】文字列の暗号化・複合化を行う。【AES暗号化】

Encode → EncodeFile

Decode → DecodeFile

 

コードを共通化することで、拡張する関数の実装が簡素化します。


using System;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;

namespace TestCode.Utility
{
    public class AesUtil
    {
        /// <summary>
        /// 共有キー
        /// </summary>
        private const string AES_KEY = "-SENJU MURAMASA-";

        /// <summary>
        /// バッファサイズ
        /// </summary>
        private const int BUFFER_SIZE = 1024 * 4;

        /// <summary>
        /// 共有キービットサイズ
        /// </summary>
        private const int KEY_SIZE = 128;

        /// <summary>
        /// 暗号操作のビットサイズ
        /// </summary>
        private const int BLOCK_SIZE = 128;

        /// <summary>
        /// 暗号化(文字列) - 入力・出力メモリストリームを共通関数へ渡す
        /// </summary>
        /// <param name="value">暗号化する文字列</param>
        /// <returns>暗号化した文字列</returns>
        static public string EncodeString(string value)
        {
            // 入力ストリーム
            using (MemoryStream inMs = new MemoryStream(Encoding.UTF8.GetBytes(value)))
            {
                // 出力ストリーム
                using (MemoryStream outMs = new MemoryStream())
                {
                    // 共通関数呼び出し
                    AesUtil.Encode(inMs, outMs);

                    // BASE64エンコードして返す
                    return Convert.ToBase64String(outMs.ToArray());
                }
            }
        }

        /// <summary>
        /// 複合化(文字列) - 入力・出力メモリストリームを共通関数へ渡す
        /// </summary>
        /// <param name="value">暗号化されている文字列</param>
        /// <returns>複合化された文字列</returns>
        static public string DecodeString(string value)
        {
            // 暗号化文字列ストリーム生成(BASE64でコード)
            using (MemoryStream inMs = new MemoryStream(Convert.FromBase64String(value), false))
            {
                // 出力ストリーム
                using (MemoryStream outMs = new MemoryStream())
                {
                    // 共通関数呼び出し
                    AesUtil.Decode(inMs, outMs);

                    // バイナリデータを文字列変換して返す
                    return Encoding.UTF8.GetString(outMs.ToArray());
                }
            }
        }

        /// <summary>
        /// 暗号化(ファイル) - 入力・出力ファイルストリームを共通関数へ渡す
        /// </summary>
        /// <param name="src">入力ファイルパス</param>
        /// <param name="dst">出力ファイルパス</param>
        static public void EncodeFile(string src, string dst)
        {
            // 入力ファイルストリーム
            using (FileStream inFs = new FileStream(src, FileMode.Open, FileAccess.Read))
            {
                // 出力ファイルストリーム
                using (FileStream outFs = new FileStream(dst, FileMode.Create, FileAccess.Write))
                {
                    // 共通関数呼び出し
                    AesUtil.Encode(inFs, outFs);
                }
            }
        }

        /// <summary>
        /// 複合化(ファイル) - 入力・出力ファイルストリームを共通関数へ渡す
        /// </summary>
        /// <param name="src">入力ファイルパス</param>
        /// <param name="dst">出力ファイルパス</param>
        static public void DecodeFile(string src, string dst)
        {
            // 入力ファイルストリーム
            using (FileStream inFs = new FileStream(src, FileMode.Open, FileAccess.Read))
            {
                // 出力ファイルストリーム
                using (FileStream outFs = new FileStream(dst, FileMode.Create, FileAccess.Write))
                {
                    // 共通関数呼び出し
                    AesUtil.Decode(inFs, outFs);
                }
            }
        }

        /// <summary>
        /// 暗号化(共通関数)- 暗号化に共通するコードを抜き出した関数
        /// </summary>
        /// <param name="src">入力ストリーム</param>
        /// <param name="dst">出力ストリーム</param>
        static private void Encode(Stream src, Stream dst)
        {
            // 高度暗号化標準 (AES) 
            using (AesManaged aes = new AesManaged())
            {
                // AESインスタンスのパラメータ設定
                aes.KeySize = KEY_SIZE;
                aes.BlockSize = BLOCK_SIZE;
                aes.Mode = CipherMode.CBC;
                aes.Key = Encoding.UTF8.GetBytes(AES_KEY);

                // 初期化ベクター(IV)の生成
                aes.GenerateIV();

                // 暗号化オブジェクト生成
                ICryptoTransform ct = aes.CreateEncryptor(aes.Key, aes.IV);

                // 初期化ベクター(IV)書き込み
                dst.Write(aes.IV, 0, aes.IV.Length);

                // 暗号変換のストリーム(暗号化)
                using (CryptoStream cs = new CryptoStream(dst, ct, CryptoStreamMode.Write))
                {
                    // Deflateアルゴリズムを使用したストリーム(圧縮)
                    using (DeflateStream ds = new DeflateStream(cs, CompressionMode.Compress))
                    {
                        byte[] buf = new byte[BUFFER_SIZE];
                        for (int size = src.Read(buf, 0, buf.Length); size > 0; size = src.Read(buf, 0, buf.Length))
                        {
                            // 出力ファイルへ書き込み(圧縮→暗号化→書き込み)
                            ds.Write(buf, 0, size);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 複合化(共通関数)- 複合化に共通するコードを抜き出した関数
        /// </summary>
        /// <param name="src">入力ストリーム</param>
        /// <param name="dst">出力ストリーム</param>
        static public void Decode(Stream src, Stream dst)
        {
            // 高度暗号化標準(AES)
            using (AesManaged aes = new AesManaged())
            {
                // AESインスタンスのパラメータ設定
                aes.KeySize = KEY_SIZE;
                aes.BlockSize = BLOCK_SIZE;
                aes.Mode = CipherMode.CBC;
                aes.Key = Encoding.UTF8.GetBytes(AES_KEY);

                // 初期化ベクター(IV)読込
                byte[] iv = new byte[aes.IV.Length];
                src.Read(iv, 0, iv.Length);
                aes.IV = iv;

                // 複合化オブジェクト生成
                ICryptoTransform ct = aes.CreateDecryptor(aes.Key, aes.IV);

                // 暗号変換のストリーム(複合化)
                using (CryptoStream cs = new CryptoStream(src, ct, CryptoStreamMode.Read))
                {
                    // Deflateアルゴリズムを使用したストリーム(圧縮解除)
                    using (DeflateStream ds = new DeflateStream(cs, CompressionMode.Decompress))
                    {
                        // 複合化した結果を書き込む
                        byte[] buf = new byte[BUFFER_SIZE];
                        for (int size = ds.Read(buf, 0, buf.Length); size > 0; size = ds.Read(buf, 0, buf.Length))
                        {
                            dst.Write(buf, 0, size);
                        }
                    }
                }
            }
        }
    }
}

入力・出力ストリームを引数として共通化することで共通関数を実装しております。

【C#】ファイルの暗号化・複合化を行う。【AES暗号化】

文字列の暗号化・複合化を行うコードの亜種としてファイルを扱う場合を記載します。

Visual Studioの環境構築




using System;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;

namespace TestCode.Utility
{
    public class AesUtil
    {
        /// <summary>
        /// 共有キー
        /// </summary>
        private const string AES_KEY = "-SENJU MURAMASA-";

        /// <summary>
        /// バッファサイズ
        /// </summary>
        private const int BUFFER_SIZE = 1024 * 4;

        /// <summary>
        /// 共有キービットサイズ
        /// </summary>
        private const int KEY_SIZE = 128;

        /// <summary>
        /// 暗号操作のビットサイズ
        /// </summary>
        private const int BLOCK_SIZE = 128;

        /// <summary>
        /// 暗号化
        /// </summary>
        /// <param name="src">入力ファイルパス</param>
        /// <param name="dst">出力ファイルパス</param>
        static public void Encode(string src, string dst)
        {
            // 高度暗号化標準 (AES) 
            using (AesManaged aes = new AesManaged())
            {
                // AESインスタンスのパラメータ設定
                aes.KeySize = KEY_SIZE;
                aes.BlockSize = BLOCK_SIZE;
                aes.Mode = CipherMode.CBC;
                aes.Key = Encoding.UTF8.GetBytes(AES_KEY);

                // 初期化ベクター(IV)の生成
                aes.GenerateIV();

                // 暗号化オブジェクト生成
                ICryptoTransform ct = aes.CreateEncryptor(aes.Key, aes.IV);

                // 出力ファイルストリーム
                using (FileStream outFs = new FileStream(dst, FileMode.Create, FileAccess.Write))
                {
                    // 初期化ベクター(IV)書き込み
                    outFs.Write(aes.IV, 0, aes.IV.Length);

                    // 暗号変換のストリーム(暗号化)
                    using (CryptoStream cs = new CryptoStream(outFs, ct, CryptoStreamMode.Write))
                    {
                        // Deflateアルゴリズムを使用したストリーム(圧縮)
                        using (DeflateStream ds = new DeflateStream(cs, CompressionMode.Compress))
                        {
                            // 入力ファイルストリーム
                            using (FileStream inFs = new FileStream(src, FileMode.Open, FileAccess.Read))
                            {
                                byte[] buf = new byte[BUFFER_SIZE];
                                for (int size = inFs.Read(buf, 0, buf.Length); size > 0; size = inFs.Read(buf, 0, buf.Length))
                                {
                                    // 出力ファイルへ書き込み(圧縮→暗号化→書き込み)
                                    ds.Write(buf, 0, size);
                                }
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 複合化
        /// </summary>
        /// <param name="src">入力ファイルパス</param>
        /// <param name="dst">出力ファイルパス</param>
        static public void Decode (string src, string dst)
        {
            // 高度暗号化標準(AES)
            using (AesManaged aes = new AesManaged())
            {
                // AESインスタンスのパラメータ設定
                aes.KeySize = KEY_SIZE;
                aes.BlockSize = BLOCK_SIZE;
                aes.Mode = CipherMode.CBC;
                aes.Key = Encoding.UTF8.GetBytes(AES_KEY);

                // 入力ファイルストリーム
                using (FileStream inFs = new FileStream(src, FileMode.Open, FileAccess.Read))
                {
                    // 初期化ベクター(IV)読込
                    byte[] iv = new byte[aes.IV.Length];
                    inFs.Read(iv, 0, iv.Length);
                    aes.IV = iv;

                    // 複合化オブジェクト生成
                    ICryptoTransform ct = aes.CreateDecryptor(aes.Key, aes.IV);

                    // 暗号変換のストリーム(複合化)
                    using (CryptoStream cs = new CryptoStream(inFs, ct, CryptoStreamMode.Read))
                    {
                        // Deflateアルゴリズムを使用したストリーム(圧縮解除)
                        using (DeflateStream ds = new DeflateStream(cs, CompressionMode.Decompress))
                        {
                            // 出力ファイルストリーム
                            using (FileStream outFs = new FileStream(dst, FileMode.Create, FileAccess.Write))
                            {
                                // 複合化した結果を書き込む
                                byte[] buf = new byte[BUFFER_SIZE];
                                for (int size = ds.Read(buf, 0, buf.Length); size > 0; size = ds.Read(buf, 0, buf.Length))
                                {
                                    outFs.Write(buf, 0, size);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

【C#】文字列の暗号化・複合化を行う。【AES暗号化】

サーバーに配置するテキストファイル内の文字列を暗号化する要件があり、暗号化及び、複合化を行う関数をまとめてみました。

Visual Studioの環境構築



そのまま張り付けるコード


using System;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;

namespace TestCode.Utility
{
    public class AesUtil
    {
        /// <summary>
        /// 共有キー
        /// </summary>
        private const string AES_KEY = "-SENJU MURAMASA-";

        /// <summary>
        /// バッファサイズ
        /// </summary>
        private const int BUFFER_SIZE = 1024 * 4;

        /// <summary>
        /// 共有キービットサイズ
        /// </summary>
        private const int KEY_SIZE = 128;

        /// <summary>
        /// 暗号操作のビットサイズ
        /// </summary>
        private const int BLOCK_SIZE = 128;

        /// <summary>
        /// 暗号化
        /// </summary>
        /// <param name="value">暗号化する文字列</param>
        /// <returns>暗号化した文字列</returns>
        static public string Encode(string value)
        {
            // 高度暗号化標準 (AES) 
            using (AesManaged aes = new AesManaged())
            {
                // AESインスタンスのパラメータ設定
                aes.KeySize = KEY_SIZE;
                aes.BlockSize = BLOCK_SIZE;
                aes.Mode = CipherMode.CBC;
                aes.Key = Encoding.UTF8.GetBytes(AES_KEY);

                // 初期化ベクター(IV)の生成
                aes.GenerateIV();

                // 暗号化オブジェクト生成
                ICryptoTransform ct = aes.CreateEncryptor(aes.Key, aes.IV);

                // 出力ストリーム
                using (MemoryStream outMs = new MemoryStream())
                {
                    // 初期化ベクター(IV)書き込み
                    outMs.Write(aes.IV, 0, aes.IV.Length);

                    // 暗号変換のストリーム(暗号化)
                    using (CryptoStream cs = new CryptoStream(outMs, ct, CryptoStreamMode.Write))
                    {
                        // Deflateアルゴリズムを使用したストリーム(圧縮)
                        using (DeflateStream ds = new DeflateStream(cs, CompressionMode.Compress))
                        {
                            // 文字列を書き込む
                            byte[] buf = Encoding.UTF8.GetBytes(value);
                            ds.Write(buf, 0, buf.Length);
                        }
                    }
                    // BASE64エンコードして返す
                    return Convert.ToBase64String(outMs.ToArray());
                }
            }
        }

        /// <summary>
        /// 複合化
        /// </summary>
        /// <param name="value">暗号化されている文字列</param>
        /// <returns>複合化された文字列</returns>
        static public string Decode(string value)
        {
            // 高度暗号化標準(AES)
            using (AesManaged aes = new AesManaged())
            {
                // AESインスタンスのパラメータ設定
                aes.KeySize = KEY_SIZE;
                aes.BlockSize = BLOCK_SIZE;
                aes.Mode = CipherMode.CBC;
                aes.Key = Encoding.UTF8.GetBytes(AES_KEY);

                // 暗号化文字列ストリーム生成(BASE64でコード)
                using (MemoryStream inMs = new MemoryStream(Convert.FromBase64String(value), false))
                {
                    // 初期化ベクター(IV)読込
                    byte[] iv = new byte[aes.IV.Length];
                    inMs.Read(iv, 0, iv.Length);
                    aes.IV = iv;

                    // 複合化オブジェクト生成
                    ICryptoTransform ct = aes.CreateDecryptor(aes.Key, aes.IV);

                    // 暗号変換のストリーム(複合化)
                    using (CryptoStream cs = new CryptoStream(inMs, ct, CryptoStreamMode.Read))
                    {
                        // Deflateアルゴリズムを使用したストリーム(圧縮解除)
                        using (DeflateStream ds = new DeflateStream(cs, CompressionMode.Decompress))
                        {
                            // 出力ストリーム
                            using (MemoryStream outMs = new MemoryStream())
                            {
                                // 複合化した結果を書き込む
                                byte[] buf = new byte[BUFFER_SIZE];
                                for (int size = ds.Read(buf, 0, buf.Length); size > 0; size = ds.Read(buf, 0, buf.Length))
                                {
                                    outMs.Write(buf, 0, size);
                                }

                                // バイナリデータを文字列変換して返す
                                return Encoding.UTF8.GetString(outMs.ToArray());
                            }
                        }
                    }
                }
            }
        }
    }
}