BookManager アプリケーションの技術資料

この技術資料は、初学者向けにBookManagerアプリケーションのコードを詳しく説明します。

概要

このアプリケーションは、書籍情報を管理し、JSONファイルに保存および読み込みを行う機能を備えています。Windows Formsを使用してGUIを作成し、ファイル操作やJSONシリアライズ/デシリアライズの方法を学ぶことができます。

必要な名前空間のインポート

まず、必要な名前空間をインポートします。これにより、後で使用するクラスやメソッドが利用可能になります。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;  // ファイル操作に必要
using System.Linq;
using Newtonsoft.Json;  // JSONシリアライズ/デシリアライズに必要
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

System.IO: ファイルの読み書き操作に必要です。

Newtonsoft.Json: JSON形式でデータをシリアライズ(オブジェクトからJSON文字列に変換)およびデシリアライズ(JSON文字列からオブジェクトに変換)するために使用します。

クラスの定義

Form1 クラス

このクラスは、Windows Formsアプリケーションのメインフォームを表します。

namespace BookManager
{
    public partial class Form1 : Form
    {
        // データ保存用のJSONファイル名を定義
        private const string FileName = @"..\..\books.json";


        public Form1()
        {
            InitializeComponent();
            // フォームの初期化時にデータを読み込む
            LoadData();
        }

        // 「追加」ボタンがクリックされたときに呼び出されるイベントハンドラ
        private void AddButtonClicked(object sender, EventArgs e)
        {
            // テキストボックスの内容をDataTableに追加
            bookDataSet.bookDataTable.AddbookDataTableRow(
                this.bookName.Text,
                this.author.Text,
                int.Parse(this.price.Text));
            // データを保存
            SaveData();
        }

        // 「削除」ボタンがクリックされたときに呼び出されるイベントハンドラ
        private void RemoveButtonClicked(object sender, EventArgs e)
        {
            // 選択した行のデータをDataTableから削除
            int row = this.bookDataGrid.CurrentRow.Index;
            this.bookDataGrid.Rows.RemoveAt(row);
            // データを保存
            SaveData();
        }

        // データをJSON形式で保存するメソッド
        private void SaveData()
        {
            // DataTableの内容をBookオブジェクトのリストに変換
            var books = new List<Book>();
            foreach (DataRow row in bookDataSet.bookDataTable.Rows)
            {
                books.Add(new Book
                {
                    BookName = row["書名"].ToString(),
                    Author = row["著者"].ToString(),
                    Price = (int)row["値段"]
                });
            }

            // BookオブジェクトのリストをJSON文字列にシリアライズ
            var json = JsonConvert.SerializeObject(books, Formatting.Indented);
            // JSON文字列をファイルに書き込む
            File.WriteAllText(FileName, json);
        }

        // JSONファイルからデータを読み込むメソッド
        private void LoadData()
        {
            // JSONファイルが存在する場合、その内容を読み込む
            if (File.Exists(FileName))
            {
                var json = File.ReadAllText(FileName);
                // JSON文字列をBookオブジェクトのリストにデシリアライズ
                var books = JsonConvert.DeserializeObject<List<Book>>(json);

                // Bookオブジェクトのリストの内容をDataTableに追加
                foreach (var book in books)
                {
                    bookDataSet.bookDataTable.AddbookDataTableRow(
                        book.BookName,
                        book.Author,
                        book.Price);
                }
            }
        }
    }

    // Bookクラスは、JSONシリアライズ/デシリアライズのためのデータモデル
    public class Book
    {
        public string BookName { get; set; }
        public string Author { get; set; }
        public int Price { get; set; }
    }
}

クラスとメソッドの詳細な説明

Form1 クラス

  • private const string FileName = @"..\..\books.json";
    • この定数は、データを保存するJSONファイルの名前を定義します。
  • public Form1():
    • フォームが初期化されるときに呼び出されるコンストラクタです。InitializeComponent();は、フォームのコントロールを初期化します。LoadData();は、フォームの初期化時にデータを読み込むメソッドです。
  • private void AddButtonClicked(object sender, EventArgs e):
    • 「追加」ボタンがクリックされたときに呼び出されるイベントハンドラです。テキストボックスの内容をbookDataSet.bookDataTableに追加し、データを保存するためにSaveData()メソッドを呼び出します。
  • private void RemoveButtonClicked(object sender, EventArgs e):
    • 「削除」ボタンがクリックされたときに呼び出されるイベントハンドラです。選択された行をbookDataGridから削除し、データを保存するためにSaveData()メソッドを呼び出します。
  • private void SaveData():
    • このメソッドは、bookDataSet.bookDataTableの内容をBookオブジェクトのリストに変換し、そのリストをJSON形式の文字列にシリアライズしてファイルに書き込みます。
    • Formatting.Indented: JSON文字列のフォーマット方法を指定します。このオプションを使うと、出力されるJSONがインデント(整形)されて、人間が読みやすくなります。
  • private void LoadData():
    • JSONファイルが存在する場合、その内容を読み込み、JSON文字列をList<Book>にデシリアライズし、そのリストの内容をbookDataSet.bookDataTableに追加します。

Book クラス

  • public class Book:
    • Bookクラスは、JSONシリアライズ/デシリアライズのためのデータモデルです。書名、著者、値段のプロパティを持っています。

実装手順

  1. プロジェクトの作成:
    • Visual Studioで新しいWindows Formsアプリケーションプロジェクトを作成します。
  2. 必要なパッケージのインストール:
    • NuGetパッケージマネージャを使用してNewtonsoft.Jsonパッケージをインストールします。
  3. 名前空間のインポート:
  4. フォームデザイン:
    • フォームにテキストボックス(書名、著者、値段)、追加ボタン、削除ボタン、およびデータグリッドビューを配置します。
  5. コードの実装:
    • 上記のForm1クラスおよびBookクラスのコードをプロジェクトに追加します。
  6. イベントハンドラの設定:

最後に

この技術資料を参考にして、書籍管理アプリケーションを実装する際の基本的な流れと方法を理解してください。特に、JSONファイルを使ったデータの保存と読み込みの方法は、さまざまなアプリケーションで役立つ知識です。

ソリューションエクスプローラで作成したJsonファイルを確認する方法

トグルになっていますので、再度クリックで表示無しになります

JSONシリアライズ/デシリアライズの説明

1. JSONとは?

JSON(JavaScript Object Notation)は、データを表現するためのシンプルなフォーマットです。人間にも機械にも読みやすく、データ交換によく使われます。

{
    "BookName": "C#入門",
    "Author": "山田太郎",
    "Price": 2500
}

2. シリアライズとは?

シリアライズは、オブジェクト(プログラム内のデータ)をJSONのような形式に変換することです。これにより、データをファイルに保存したり、ネットワーク経由で送信したりできます。

簡単に言うと:

  • オブジェクト → JSON

例: C#のBookオブジェクトをJSONに変換する

Book myBook = new Book { BookName = "C#入門", Author = "山田太郎", Price = 2500 };
string json = JsonConvert.SerializeObject(myBook);
// json: {"BookName":"C#入門","Author":"山田太郎","Price":2500}

3. デシリアライズとは?

デシリアライズは、JSONのような形式からオブジェクトに変換することです。これにより、保存したデータを再びプログラム内で使えるようになります。

簡単に言うと:

  • JSON → オブジェクト

例: JSONからC#のBookオブジェクトに変換する

string json = "{\"BookName\":\"C#入門\",\"Author\":\"山田太郎\",\"Price\":2500}";
Book myBook = JsonConvert.DeserializeObject<Book>(json);
// myBook: Bookオブジェクト { BookName = "C#入門", Author = "山田太郎", Price = 2500 }

実際にやってみよう!

シリアライズの手順:

  1. オブジェクトを作成
  2. JsonConvert.SerializeObjectでJSONに変換
Book myBook = new Book { BookName = "C#入門", Author = "山田太郎", Price = 2500 };
string json = JsonConvert.SerializeObject(myBook);
Console.WriteLine(json); // {"BookName":"C#入門","Author":"山田太郎","Price":2500}

デシリアライズの手順:

  1. JSON文字列を用意
  2. JsonConvert.DeserializeObjectでオブジェクトに変換
string json = "{\"BookName\":\"C#入門\",\"Author\":\"山田太郎\",\"Price\":2500}";
Book myBook = JsonConvert.DeserializeObject<Book>(json);
Console.WriteLine(myBook.BookName); // C#入門

最後に

シリアライズとデシリアライズを使えば、プログラムのデータを簡単に保存・読み込みできるようになります。最初はシンプルな例から始めて、少しずつ慣れていきましょう。

補足(オブション)

データグリッドビューでデータテーブルを列幅いっぱいに表示したい

bookDataGrid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;

このコードは、DataGridViewの列幅を自動的にグリッド全体の幅に合わせてくれます。 AutoSizeColumnsModeプロパティを Fill に設定することで、各列が均等に幅を割り当てられます。

セルの値を直接変更できないようにしたい

// 各列を読み取り専用に設定
foreach (DataGridViewColumn column in bookDataGrid.Columns)
{
    column.ReadOnly = true;
}

このコードでは、DataGridViewの各列を読み取り専用に設定することで、セルの値を直接変更できないようにしています。これにより、データが表示されるだけで、ユーザーはセルの内容を編集することができなくなります。

また、DataGridViewを選択し、ビジュアルでの設定も可能です

セルを選択すると行全部が選択されるようにしたい

// 行全体を選択するように設定
bookDataGrid.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
bookDataGrid.MultiSelect = false; // 必要に応じて複数選択を無効化

このコードでは、dataGridView1.SelectionModeDataGridViewSelectionMode.FullRowSelectに設定することで、セルをクリックすると行全体が選択されるようになります。また、MultiSelectプロパティをfalseに設定することで、複数行の選択を無効化しています。複数行の選択を許可したい場合は、この行を削除するか、trueに設定してください。

選択された行の値が入力用のテキストボックスに反映されるようにしたい

// 選択された行のデータをテキストボックスに反映するメソッド
private void BookDataGrid_SelectionChanged(object sender, EventArgs e)
{
    if (bookDataGrid.CurrentRow != null)
    {
        DataGridViewRow currentRow = bookDataGrid.CurrentRow;
        this.bookName.Text = currentRow.Cells["書名DataGridViewTextBoxColumn"].Value.ToString();
        this.author.Text = currentRow.Cells["著者DataGridViewTextBoxColumn"].Value.ToString();
        this.price.Text = currentRow.Cells["値段DataGridViewTextBoxColumn"].Value.ToString();
    }
}

選択された行のデータを入力用のテキストボックスに反映させるには、DataGridViewSelectionChangedイベントを利用します。このイベントハンドラで、選択された行のデータをテキストボックスに表示するようにします。

  1. SelectionChangedイベントの追加:
    • Form1コンストラクタ内で、bookDataGrid.SelectionChangedイベントにBookDataGrid_SelectionChangedメソッドを追加します。
  2. BookDataGrid_SelectionChangedメソッド:
    • このメソッドは、選択された行が変更されたときに呼び出されます。
    • bookDataGrid.CurrentRowを使用して現在選択されている行を取得し、そのセルの値をテキストボックスに設定します。

使用方法

  1. アプリケーションを起動して、DataGridViewの行をクリックします。
  2. 選択した行のデータが入力用のテキストボックスに表示されます。

このようにして、選択された行のデータを簡単に入力用のテキストボックスに反映させることができます。

重複追加をできないようにしたい

重複追加を防ぐためには、新しいエントリを追加する前に、既存のデータセット内に同じ書名が存在するかどうかを確認する必要があります。以下のコードでは、重複をチェックするロジックをAddButtonClickedメソッドに追加しています。

foreach (DataRow row in bookDataSet.bookDataTable.Rows)
{
    if (row["書名"].ToString() == this.bookName.Text)
    {
        MessageBox.Show("同じ書名の本が既に存在します。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }
}

重複チェックの追加:

  • AddButtonClickedメソッド内で、データテーブルの各行をループして、新しい書名が既に存在するかどうかを確認します。
  • 既存の書名と一致する場合、メッセージボックスを表示して処理を中断します。

メッセージボックスの表示:

  • 重複が見つかった場合に、ユーザーにエラーメッセージを表示します。

使用方法

  1. アプリケーションを起動して、DataGridViewにデータを追加します。
  2. 同じ書名の本を追加しようとすると、エラーメッセージが表示され、追加が中断されます。

これで、重複した書名の本を追加できないようになりました。

データ追加後に入力フィールドをクリアすることで、ユーザーが次のデータを入力しやすくします

データ追加後に入力フィールドをクリアするためには、データ追加の処理の後に入力フィールドをクリアするメソッドを呼び出します。

// 入力フィールドをクリアするメソッド
private void ClearInputFields()
{
    this.bookName.Clear();
    this.author.Clear();
    this.price.Clear();
}

AddButtonClickedメソッドの修正:

  • データを追加した後に、ClearInputFieldsメソッドを呼び出して入力フィールドをクリアします。
ClearInputFields(); // データ追加後に入力フィールドをクリア

使用方法

  1. アプリケーションを起動して、新しい書籍情報を入力し、「追加」ボタンをクリックします。
  2. データが追加された後、入力フィールドが自動的にクリアされ、次のデータを入力できるようになります。

この修正により、データを追加した後に入力フィールドがクリアされ、ユーザーが次のデータを簡単に入力できるようになります。

入力ごとに右寄せされる、またカーソル入力位置は常に右端にしたい(TextBoxコントロールを使います。MaskedTextBoxではありません)

レジ入力のように右端から入力するようにしたい場合など

TextBoxのTextAlignプロパティをRightに設定

TextChangedイベントを利用してカーソル位置を常に右端に設定

private void TextBox_TextChanged(object sender, EventArgs e)
{
    TextBox textBox = sender as TextBox;

    // カーソルをテキストの右端に移動
    textBox.SelectionStart = textBox.Text.Length;
    textBox.SelectionLength = 0;
}

参考