【C#】課題: 図書管理システム(BookManagement)の作成

2024年7月30日

前回の課題で、簡易電話帳アプリケーションを作成しました。このアプリケーションでは、ListBoxに名前を表示し、選択された名前に対応する電話番号を表示する機能を実装しました。今回は、これを基にして、図書管理システムを作成します。

課題

課題の目的

この課題を通して、以下のスキルを学びます:

  • C#のクラス設計
  • ファイルからデータを読み込む方法
  • コレクションの操作方法
  • イベント処理の実装
  • Windows Formsを使用したデスクトップアプリケーションの開発

課題内容

日本語の本の情報を表示する図書管理システムを作成します。このシステムでは、ListBoxに本のタイトルを表示し、選択されたタイトルに対応する本の詳細情報(著者、ページ数、評価)を表示します。

プロジェクトの概要

このプロジェクトでは、次の機能を持つ図書管理アプリケーションを作成します。

  1. ファイルから本の情報を読み込む。
  2. 読み込んだ本のタイトルをリストに表示する。
  3. 選択した本の詳細情報を表示する。

コードの解説

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

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
  • SystemSystem.Collections.Genericなどの名前空間を使用して、基本的な機能やコレクション、Windowsフォームの機能を利用します。

2. メインフォームクラスの定義

namespace BookManagement
{
    public partial class Form1 : Form
    {
        Dictionary<string, Book> bookCollection;

        public Form1()
        {
            InitializeComponent();

            // 図書管理に本を登録する
            this.bookCollection = new Dictionary<string, Book>();

            // ファイルからデータを読み込む
            ReadFromFile();

            // リストにタイトルを表示する
            foreach (KeyValuePair<string, Book> data in bookCollection)
            {
                this.titleList.Items.Add(data.Key);
            }
        }
  • Form1クラスはWindowsフォームを表します。このクラスの中で本のコレクションを保持するDictionaryと、コンストラクタ内で初期化処理を行います。

3. ファイルからデータを読み込むメソッド

        private void ReadFromFile()
        {
            using (System.IO.StreamReader file =
                    new System.IO.StreamReader(@"..\..\data.txt"))
            {
                while (!file.EndOfStream)
                {
                    string line = file.ReadLine();
                    string[] data = line.Split(',');
                    string title = data[0];
                    string author = data[1];
                    int pages = int.Parse(data[2]);
                    int rating = int.Parse(data[3]);
                    this.bookCollection.Add(title, new Book(title, author, pages, rating));
                }
            }
        }
  • ReadFromFileメソッドでは、data.txtファイルから本の情報を読み込み、bookCollectionに追加します。

4. タイトル選択時に本の情報を表示するメソッド

        private void TitleSelected(object sender, EventArgs e)
        {
            // 選択したタイトルに対応する本の情報を表示する
            string title = this.titleList.Text;
            if (this.bookCollection.ContainsKey(title))
            {
                Book selectedBook = this.bookCollection[title];
                this.bookDetails.Text = $"Title: {selectedBook.Title}\nAuthor: {selectedBook.Author}\nPages: {selectedBook.Pages}\nRating: {selectedBook.Rating}";
            }
        }
    }
  • TitleSelectedメソッドでは、リストから選択したタイトルに対応する本の情報を表示します。

5. 本を表すクラス

    public class Book
    {
        public string Title { get; set; }
        public string Author { get; set; }
        public int Pages { get; set; }
        public int Rating { get; set; }

        public Book(string title, string author, int pages, int rating)
        {
            Title = title;
            Author = author;
            Pages = pages;
            Rating = rating;
        }
    }
}
  • Bookクラスは、本の情報(タイトル、著者、ページ数、評価)を保持します。

6. フォームの初期化とUI要素の定義

namespace BookManagement
{
    partial class Form1
    {
        private System.ComponentModel.IContainer components = null;
        private System.Windows.Forms.ListBox titleList;
        private System.Windows.Forms.Label bookDetails;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.titleList = new System.Windows.Forms.ListBox();
            this.bookDetails = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // titleList
            // 
            this.titleList.ItemHeight = 24;
            this.titleList.Location = new System.Drawing.Point(12, 12);
            this.titleList.Name = "titleList";
            this.titleList.Size = new System.Drawing.Size(200, 172);
            this.titleList.TabIndex = 0;
            this.titleList.SelectedIndexChanged += new System.EventHandler(this.TitleSelected);
            // 
            // bookDetails
            // 
            this.bookDetails.AutoSize = true;
            this.bookDetails.Location = new System.Drawing.Point(218, 12);
            this.bookDetails.Name = "bookDetails";
            this.bookDetails.Size = new System.Drawing.Size(67, 24);
            this.bookDetails.TabIndex = 1;
            this.bookDetails.Text = "label1";
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(400, 211);
            this.Controls.Add(this.bookDetails);
            this.Controls.Add(this.titleList);
            this.Name = "Form1";
            this.Text = "Book Management";
            this.ResumeLayout(false);
            this.PerformLayout();
        }
    }
}
  • InitializeComponentメソッドで、フォームのUI要素(リストボックスとラベル)を初期化し、配置します。

実行手順

  1. data.txtファイルをプロジェクトのルートディレクトリに配置し、次のような形式でデータを入力します。

吾輩は猫である,夏目漱石,200,5
こころ,夏目漱石,250,4
坊っちゃん,夏目漱石,180,4
雪国,川端康成,300,5
人間失格,太宰治,220,4

  1. プロジェクトをビルドし、実行します。
  2. アプリケーションが起動すると、リストに本のタイトルが表示されます。
  3. タイトルを選択すると、右側に本の詳細情報が表示されます。

コード全体

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BookManagement
{
    public partial class Form1 : Form
    {
        Dictionary<string, Book> bookCollection;

        public Form1()
        {
            InitializeComponent();

            // 図書管理に本を登録する
            this.bookCollection = new Dictionary<string, Book>();

            // ファイルからデータを読み込む
            ReadFromFile();

            // リストにタイトルを表示する
            foreach (KeyValuePair<string, Book> data in bookCollection)
            {
                this.titleList.Items.Add(data.Key);
            }
        }

        private void ReadFromFile()
        {
            using (System.IO.StreamReader file =
                    new System.IO.StreamReader(@"..\..\data.txt"))
            {
                while (!file.EndOfStream)
                {
                    string line = file.ReadLine();
                    string[] data = line.Split(',');
                    string title = data[0];
                    string author = data[1];
                    int pages = int.Parse(data[2]);
                    int rating = int.Parse(data[3]);
                    this.bookCollection.Add(title, new Book(title, author, pages, rating));
                }
            }
        }

        private void TitleSelected(object sender, EventArgs e)
        {
            // 選択したタイトルに対応する本の情報を表示する
            string title = this.titleList.Text;
            if (this.bookCollection.ContainsKey(title))
            {
                Book selectedBook = this.bookCollection[title];
                this.bookDetails.Text = $"Title: {selectedBook.Title}\nAuthor: {selectedBook.Author}\nPages: {selectedBook.Pages}\nRating: {selectedBook.Rating}";
            }
        }
    }

    public class Book
    {
        public string Title { get; set; }
        public string Author { get; set; }
        public int Pages { get; set; }
        public int Rating { get; set; }

        public Book(string title, string author, int pages, int rating)
        {
            Title = title;
            Author = author;
            Pages = pages;
            Rating = rating;
        }
    }
}
namespace BookManagement
{
    partial class Form1
    {
        private System.ComponentModel.IContainer components = null;
        private System.Windows.Forms.ListBox titleList;
        private System.Windows.Forms.Label bookDetails;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.titleList = new System.Windows.Forms.ListBox();
            this.bookDetails = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // titleList
            // 
            this.titleList.ItemHeight = 24;
            this.titleList.Location = new System.Drawing.Point(12, 12);
            this.titleList.Name = "titleList";
            this.titleList.Size = new System.Drawing.Size(200, 172);
            this.titleList.TabIndex = 0;
            this.titleList.SelectedIndexChanged += new System.EventHandler(this.TitleSelected);
            // 
            // bookDetails
            // 
            this.bookDetails.AutoSize = true;
            this.bookDetails.Location = new System.Drawing.Point(218, 12);
            this.bookDetails.Name = "bookDetails";
            this.bookDetails.Size = new System.Drawing.Size(67, 24);
            this.bookDetails.TabIndex = 1;
            this.bookDetails.Text = "label1";
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(400, 211);
            this.Controls.Add(this.bookDetails);
            this.Controls.Add(this.titleList);
            this.Name = "Form1";
            this.Text = "Book Management";
            this.ResumeLayout(false);
            this.PerformLayout();

        }
    }
}

おまけ

要素番号(インデックス)を取得する方法

はじめに

この資料では、ListBoxやComboBoxなどのコントロールから選択されたアイテムの要素番号(インデックス)を取得する方法について説明します。具体的な例として、選択されたタイトルに対応する本の情報を表示するコードを使います。

例:選択されたタイトルに対応する本の情報を表示する

まず、ListBoxやComboBoxから選択されたアイテムのインデックスを取得する方法を説明します。次のコードは、ListBoxやComboBoxで選択されたタイトルのインデックスを取得し、そのインデックスを使用して本の情報を表示する例です。

private void TitleSelected(object sender, EventArgs e)
{
    // 選択したタイトルのインデックスを取得
    int selectedIndex = this.titleList.SelectedIndex;

    // 有効なインデックスが選択されているかチェック
    if (selectedIndex != -1)
    {
        // インデックスを使用して選択されたタイトルを取得
        string title = this.titleList.Items[selectedIndex].ToString();

        // 本のコレクションに選択されたタイトルが含まれているか確認
        if (this.bookCollection.ContainsKey(title))
        {
            // 選択された本の情報を取得
            Book selectedBook = this.bookCollection[title];

            // 本の情報を表示する
            this.bookDetails.Text = $"Title: {selectedBook.Title}\nAuthor: {selectedBook.Author}\nPages: {selectedBook.Pages}\nRating: {selectedBook.Rating}";
        }
    }
}

コードの詳細説明

選択されたインデックスの取得

int selectedIndex = this.titleList.SelectedIndex;

ListBoxやComboBoxから選択されたアイテムのインデックスをSelectedIndexプロパティから取得します。

有効なインデックスのチェック

if (selectedIndex != -1)

SelectedIndex-1でないことを確認します。-1は何も選択されていないことを意味します。

インデックスを使用してアイテムを取得

string title = this.titleList.Items[selectedIndex].ToString();

Itemsコレクションから選択されたインデックスに対応するアイテムを取得し、ToString()メソッドを使用して文字列として取得します。

本の情報を表示

if (this.bookCollection.ContainsKey(title))
{
    Book selectedBook = this.bookCollection[title];
    this.bookDetails.Text = $"Title: {selectedBook.Title}\nAuthor: {selectedBook.Author}\nPages: {selectedBook.Pages}\nRating: {selectedBook.Rating}";
}

取得したタイトルをキーとして本のコレクション(bookCollection)から本の情報を取得し、bookDetailsテキストボックスに表示します。

まとめ

ListBoxやComboBoxなどのコントロールから選択されたアイテムのインデックスを取得することで、選択されたアイテムに基づいた処理を行うことができます。この技術は、ユーザーが選択した情報に応じて動的に内容を更新する際に非常に有用です。