前回までの概要
前前回まででタスク管理アプリの大枠作成、ブラッシュアップをしました。
今回はタスク登録画面の内容見直し、ブラッシュアップを行います。
プロンプト
タスク編集画面へ以下の機能修正を行いたい
優先度、ステータスの日本語化
遅延自動判定
遅延理由項目追加
遅延理由自動付与
項目を2列で表示
回答
修正方針
以下4機能を追加します。
| 機能 | 内容 |
|---|---|
| 優先度/ステータス日本語化 | enum表示改善 |
| 遅延自動判定 | 自動で遅延ON |
| 遅延理由追加 | 入力欄追加 |
| 遅延理由自動設定 | 自動メッセージ |
| 2列レイアウト化 | UI改善 |
修正対象
| ファイル | 内容 |
|---|---|
| TaskItem.cs | 遅延理由追加 |
| TaskEditForm.Designer.cs | UI大幅変更 |
| TaskEditForm.cs | 遅延自動判定 |
| Priority.cs | 日本語化 |
| TaskStatus.cs | 日本語化 |
1. TaskItem.cs 修正
追加
public string DelayReason
{
get;
set;
} = string.Empty;
2. Priority enum 日本語化
修正前
public enum Priority
{
Low,
Medium,
High
}
修正後
using System.ComponentModel;
namespace TaskManager.Domain
{
public enum Priority
{
[Description("低")]
Low,
[Description("中")]
Medium,
[Description("高")]
High
}
}
3. TaskStatus enum 日本語化
修正後
using System.ComponentModel;
namespace TaskManager.Domain
{
public enum TaskStatus
{
[Description("未着手")]
NotStarted,
[Description("作業中")]
InProgress,
[Description("完了")]
Completed,
[Description("保留")]
OnHold
}
}
4. Enum表示Helper追加
新規 EnumHelper.cs
using System.ComponentModel;
using System.Reflection;
namespace TaskManager.Common
{
public static class EnumHelper
{
public static string GetDescription(
Enum value)
{
FieldInfo? field =
value.GetType()
.GetField(value.ToString());
if (field == null)
{
return value.ToString();
}
var attr =
field.GetCustomAttribute<
DescriptionAttribute>();
return attr?.Description
?? value.ToString();
}
}
}
5. TaskEditForm.Designer.cs 修正
レイアウト変更方針
左列:基本情報
右列:工数・管理情報
フォームサイズ変更
ClientSize =
new Size(1000, 750);
位置変更例
左列
lblTaskName.Location =
new Point(20, 20);
txtTaskName.Location =
new Point(140, 20);
lblDescription.Location =
new Point(20, 60);
txtDescription.Location =
new Point(140, 60);
lblStartDate.Location =
new Point(20, 220);
dtpStartDate.Location =
new Point(140, 220);
右列
lblAssignee.Location =
new Point(520, 20);
cmbAssignee.Location =
new Point(680, 20);
lblPlannedHours.Location =
new Point(520, 60);
numPlannedHours.Location =
new Point(680, 60);
lblActualHours.Location =
new Point(520, 100);
numActualHours.Location =
new Point(680, 100);
遅延理由追加
フィールド追加
private Label lblDelayReason;
private TextBox txtDelayReason;
InitializeComponent追加
lblDelayReason =
new Label();
lblDelayReason.Text =
"遅延理由";
lblDelayReason.Location =
new Point(520, 260);
txtDelayReason =
new TextBox();
txtDelayReason.Location =
new Point(680, 260);
txtDelayReason.Width = 250;
txtDelayReason.Height = 100;
txtDelayReason.Multiline = true;
Controls追加
Controls.Add(lblDelayReason);
Controls.Add(txtDelayReason);
6. TaskEditForm.cs 修正
using追加
using TaskManager.Common;
日本語表示用ロード修正
優先度
cmbPriority.Items.Clear();
foreach (Priority p
in Enum.GetValues(
typeof(Priority)))
{
cmbPriority.Items.Add(p);
}
cmbPriority.Format +=
(s, e) =>
{
if (e.ListItem is Enum en)
{
e.Value =
EnumHelper
.GetDescription(en);
}
};
ステータス
cmbStatus.Items.Clear();
foreach (TaskStatus s
in Enum.GetValues(
typeof(TaskStatus)))
{
cmbStatus.Items.Add(s);
}
cmbStatus.Format +=
(s, e) =>
{
if (e.ListItem is Enum en)
{
e.Value =
EnumHelper
.GetDescription(en);
}
};
7. 遅延自動判定追加
メソッド追加
private void UpdateDelayStatus()
{
bool delayed = false;
string reason = "";
if (DateTime.Today >
dtpEndDate.Value.Date
&&
cmbStatus.SelectedItem
is not TaskStatus.Completed)
{
delayed = true;
reason =
"終了予定日を超過しています。";
}
if (numActualHours.Value >
numPlannedHours.Value)
{
delayed = true;
if (!string.IsNullOrWhiteSpace(reason))
{
reason += Environment.NewLine;
}
reason +=
"実績工数が予定工数を超過しています。";
}
chkIsDelayed.Checked =
delayed;
if (string.IsNullOrWhiteSpace(
txtDelayReason.Text))
{
txtDelayReason.Text =
reason;
}
}
イベント追加
コンストラクタ。
dtpEndDate.ValueChanged +=
(_, _) => UpdateDelayStatus();
cmbStatus.SelectedIndexChanged +=
(_, _) => UpdateDelayStatus();
numActualHours.ValueChanged +=
(_, _) => UpdateDelayStatus();
numPlannedHours.ValueChanged +=
(_, _) => UpdateDelayStatus();
8. LoadTask() 修正
追加
txtDelayReason.Text =
_editTarget.DelayReason;
9. CreateTask() 修正
追加
DelayReason =
txtDelayReason.Text,
10. UpdateTask() 修正
追加
_editTarget.DelayReason =
txtDelayReason.Text;
11. 保存前自動判定(重要)
Saveボタン押下前
UpdateDelayStatus();
を必ず呼ぶ。
完成後UIイメージ
┌────────────────────────────────────┐
│タスク名 │担当者 │
│説明 │カテゴリ │
│開始予定 │工程 │
│終了予定 │予定工数 │
│開始実績 │実績工数 │
│終了実績 │残工数 │
│進捗 │優先度 │
│ステータス │遅延 │
│ │遅延理由 │
└────────────────────────────────────┘
遅延自動判定例
ケース1
終了予定:昨日
ステータス:作業中
↓
遅延ON
理由:
終了予定日を超過しています。
ケース2
予定工数:10
実績工数:15
↓
遅延ON
理由:
実績工数が予定工数を超過しています。
実装、起動確認
まとめ
WBSの実用化も一旦完了かと思います。
次回はWBS画面を修正していきます。
