【Winform】中級:JSON ベースのタスク管理アプリの作成
このドキュメントでは、C# と WinForm (.NET Framework) を使用し、JSON を使ってデータを管理するタスク管理アプリを作成する方法を解説します。初学者でも理解しやすいよう、丁寧に手順を説明しています。
概要
このアプリは、DateTime
をキーとする Dictionary
でタスクを管理し、JSON ファイルを使用してデータの保存と読み込みを行います。アプリは、タスクの追加、編集、削除ができ、アプリを再起動してもデータが保持されます。UI は Visual Studio のビジュアルデザイナーを使って配置します。
プロジェクトのセットアップ
- Visual Studio の起動
Visual Studio を開き、新しい「Windows フォームアプリケーション (.NET Framework)」プロジェクトを作成します。 - プロジェクトの命名
プロジェクト名を「TaskManager」とし、Form1
の名前をTaskManagerForm
に変更します。フォームのタイトル(Text プロパティ)も「タスク管理アプリ」に設定します。
UI の配置
ビジュアルデザイナーを使ったレイアウト設定
以下の手順に従って、UIコントロールをフォーム上に配置します。
- コントロールの追加と配置
- Visual Studio のツールボックスから以下のコントロールをフォームにドラッグ&ドロップします。
TextBox
(taskNameTextBox
): フォーム上部に配置し、タスク名を入力できるようにします。MonthCalendar
(monthCalendar
):TextBox
の下に配置し、タスクの期限をカレンダーで選択できるようにします。ListView
(taskListView
):MonthCalendar
の下に配置し、タスク一覧を表示します。
- Visual Studio のツールボックスから以下のコントロールをフォームにドラッグ&ドロップします。
ListView
の設定ListView
を選択し、Visual Studio のプロパティウィンドウで次の設定を行います。- View:
Details
に設定します。これにより、タスクの詳細がリスト形式で表示されます。 - FullRowSelect:
True
に設定します。これにより、行全体を選択できるようになります。 - GridLines:
True
に設定します。これにより、リストにグリッドラインが表示され、項目を見やすくします。 - Columns:
Columns
プロパティをクリックし、「列の追加」ダイアログを開きます。以下の2つの列を追加します:Header Text
: タスク名,Width
: 150Header Text
: 締切日,Width
: 150
- View:
- ボタンの配置
Button
(addButton
、deleteButton
)をフォームの適切な位置に配置します。ボタンのDock
設定は不要です。ボタンはタスクの追加および削除を行うために使用されます。
- イベントハンドラーの設定
taskListView
のSelectedIndexChanged
イベントを設定し、項目が選択されたときにtaskNameTextBox
にタスク名が表示されるようにします。
各コントロールをビジュアルデザイナーで配置した場合、以下のように InitializeComponent
メソッドが自動生成されます。
namespace TaskManager
{
partial class TaskManagerForm
{
/// <summary>
/// 必要なデザイナー変数です。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 使用中のリソースをすべてクリーンアップします。
/// </summary>
/// <param name="disposing">マネージド リソースを破棄する場合は true を指定し、その他の場合は false を指定します。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows フォーム デザイナーで生成されたコード
/// <summary>
/// デザイナー サポートに必要なメソッドです。このメソッドの内容を
/// コード エディターで変更しないでください。
/// </summary>
private void InitializeComponent()
{
this.taskNameTextBox = new System.Windows.Forms.TextBox();
this.monthCalendar = new System.Windows.Forms.MonthCalendar();
this.addButton = new System.Windows.Forms.Button();
this.deleteButton = new System.Windows.Forms.Button();
this.taskListView = new System.Windows.Forms.ListView();
this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// taskNameTextBox
//
this.taskNameTextBox.Location = new System.Drawing.Point(240, 360);
this.taskNameTextBox.Name = "taskNameTextBox";
this.taskNameTextBox.Size = new System.Drawing.Size(300, 19);
this.taskNameTextBox.TabIndex = 0;
//
// monthCalendar
//
this.monthCalendar.Location = new System.Drawing.Point(30, 271);
this.monthCalendar.Name = "monthCalendar";
this.monthCalendar.TabIndex = 1;
this.monthCalendar.DateSelected += new System.Windows.Forms.DateRangeEventHandler(this.MonthCalendar_DateSelected);
//
// addButton
//
this.addButton.Location = new System.Drawing.Point(280, 400);
this.addButton.Name = "addButton";
this.addButton.Size = new System.Drawing.Size(100, 30);
this.addButton.TabIndex = 3;
this.addButton.Text = "追加";
this.addButton.Click += new System.EventHandler(this.AddButton_Click);
//
// deleteButton
//
this.deleteButton.Location = new System.Drawing.Point(410, 400);
this.deleteButton.Name = "deleteButton";
this.deleteButton.Size = new System.Drawing.Size(100, 30);
this.deleteButton.TabIndex = 5;
this.deleteButton.Text = "削除";
this.deleteButton.Click += new System.EventHandler(this.DeleteButton_Click);
//
// taskListView
//
this.taskListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader3,
this.columnHeader4});
this.taskListView.FullRowSelect = true;
this.taskListView.GridLines = true;
this.taskListView.HideSelection = false;
this.taskListView.Location = new System.Drawing.Point(30, 30);
this.taskListView.Name = "taskListView";
this.taskListView.Size = new System.Drawing.Size(500, 200);
this.taskListView.TabIndex = 6;
this.taskListView.UseCompatibleStateImageBehavior = false;
this.taskListView.View = System.Windows.Forms.View.Details;
this.taskListView.SelectedIndexChanged += new System.EventHandler(this.TaskListView_SelectedIndexChanged);
//
// columnHeader3
//
this.columnHeader3.Text = "タスク名";
this.columnHeader3.Width = 350;
//
// columnHeader4
//
this.columnHeader4.Text = "締切日";
this.columnHeader4.Width = 150;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(240, 340);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(42, 12);
this.label1.TabIndex = 7;
this.label1.Text = "タスク名";
//
// TaskManagerForm
//
this.ClientSize = new System.Drawing.Size(564, 461);
this.Controls.Add(this.label1);
this.Controls.Add(this.taskListView);
this.Controls.Add(this.taskNameTextBox);
this.Controls.Add(this.monthCalendar);
this.Controls.Add(this.addButton);
this.Controls.Add(this.deleteButton);
this.Name = "TaskManagerForm";
this.Text = "タスク管理アプリ";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button addButton;
private System.Windows.Forms.Button deleteButton;
private System.Windows.Forms.TextBox taskNameTextBox;
private System.Windows.Forms.MonthCalendar monthCalendar;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.ListView taskListView;
private System.Windows.Forms.ColumnHeader columnHeader3;
private System.Windows.Forms.ColumnHeader columnHeader4;
private System.Windows.Forms.Label label1;
}
}
ビジュアルデザイナーでの設定結果
これらの操作を行うことで、レイアウトが自動的に InitializeComponent
メソッドに反映されます。特にコードを手動で編集する必要はありません。
タスクのデータ管理を JSON で行う
データモデルの作成
タスクを管理するために Dictionary<DateTime, string>
を使用します。
コード例
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Windows.Forms;
namespace TaskManager
{
public partial class TaskManagerForm : Form
{
private Dictionary<DateTime, string> tasks;
private const string DataFileName = "tasks.json";
public TaskManagerForm()
{
InitializeComponent();
tasks = LoadTasks();
UpdateTaskListView();
}
private void AddButton_Click(object sender, EventArgs e)
{
DateTime selectedDate = monthCalendar.SelectionStart;
string taskName = taskNameTextBox.Text;
tasks[selectedDate] = taskName;
UpdateTaskListView();
SaveTasks();
}
private void DeleteButton_Click(object sender, EventArgs e)
{
if (taskListView.SelectedIndices.Count > 0)
{
// ListView で選択された項目のインデックスを取得
int index = taskListView.SelectedIndices[0];
// 選択されたタスクの締切日を取得
DateTime selectedDate = DateTime.Parse(taskListView.Items[index].SubItems[1].Text);
// 締切日をキーに辞書からタスクを削除
if (tasks.ContainsKey(selectedDate))
{
tasks.Remove(selectedDate);
}
// ListView を更新し、TextBox をクリア
UpdateTaskListView();
taskNameTextBox.Clear();
// 変更を保存
SaveTasks();
}
}
private void TaskListView_SelectedIndexChanged(object sender, EventArgs e)
{
if (taskListView.SelectedIndices.Count > 0)
{
int index = taskListView.SelectedIndices[0];
DateTime selectedDate = DateTime.Parse(taskListView.Items[index].SubItems[1].Text);
// テキストボックスにタスク名を表示
taskNameTextBox.Text = taskListView.Items[index].SubItems[0].Text;
// カレンダーに該当の日付を表示
monthCalendar.SetDate(selectedDate);
}
}
private void MonthCalendar_DateSelected(object sender, DateRangeEventArgs e)
{
DateTime selectedDate = e.Start;
if (tasks.ContainsKey(selectedDate))
{
taskNameTextBox.Text = tasks[selectedDate];
}
else
{
taskNameTextBox.Clear();
}
}
private void UpdateTaskListView()
{
taskListView.Items.Clear();
// タスクを締切日でソート
var sortedTasks = tasks.OrderBy(task => task.Key);
foreach (var task in sortedTasks)
{
var item = new ListViewItem(task.Value);
item.SubItems.Add(task.Key.ToShortDateString());
taskListView.Items.Add(item);
}
}
private void SaveTasks()
{
var options = new JsonSerializerOptions { WriteIndented = true };
File.WriteAllText(DataFileName, JsonSerializer.Serialize(tasks, options));
}
private Dictionary<DateTime, string> LoadTasks()
{
if (File.Exists(DataFileName))
{
string jsonData = File.ReadAllText(DataFileName);
return JsonSerializer.Deserialize<Dictionary<DateTime, string>>(jsonData);
}
return new Dictionary<DateTime, string>();
}
}
}
タスクの追加、編集、削除
1. タスクの追加
- 操作:
TextBox
にタスク名を入力し、MonthCalendar
で日付を選択した後、追加
ボタンをクリックします。 - 結果: 新しいタスクが
tasks
辞書に追加され、ListView
に表示されます。既存のタスクが選択された場合、そのタスクの内容が上書きされます。ListView
に表示されるタスクは、締切日でソートされます。
2. タスクの編集
- 操作:
ListView
で編集したいタスクを選択すると、そのタスク名がTextBox
に表示され、対応する日付がMonthCalendar
に反映されます。TextBox
の内容を変更し、必要であればMonthCalendar
で日付を変更した後、追加
ボタンをクリックします。 - 結果: 既存のタスクの内容が更新されます。元のタスクは削除され、新しい情報でタスクが再登録されます。
ListView
は締切日でソートされます。
3. タスクの削除
- 操作:
ListView
で削除したいタスクを選択し、削除
ボタンをクリックします。 - 結果: 選択されたタスクが
tasks
辞書およびListView
から削除されます。削除後、TextBox
の内容もクリアされます。ListView
は締切日でソートされます。
JSONを使ったデータの保存と読み込み
アプリケーションを再起動してもタスクが保持されるように、JSON形式でデータを保存・読み込みします。
まとめ
このドキュメントでは、C# と WinForm (.NET Framework) を使い、JSONを利用したタスク管理アプリの作成方法を解説しました。UIの配置は Visual Studio のビジュアルデザイナーを使用して整理し、データの管理には DateTime
をキーとする Dictionary
と JSON を用いました。初学者でも理解しやすい手順で、実際に使えるシンプルなアプリケーションを構築するスキルが身につきます。
ディスカッション
コメント一覧
まだ、コメントがありません