← 기사 목록
日本語https://qiita.com/tags/ai/feed

AIに頼り切ってタスクアプリを追加開発する。:ファイルアップロード機能追加

추출된 키워드

20
タスクアプリ·5ファイルアップロード機能·5AI·5プロンプト·4DataGridView·4添付ファイル管理·3TaskItem.json·3JSON·3OpenFileDialog·3TaskEditForm.cs·3TaskEditForm.Designer.cs·3TaskItem.cs·3ReadOnly·3CSV·2Excel·2DragDrop·2PDFプレビュー·2UX·2ProcessStartInfo·2System.IO·2

원문

9,832
AIに頼り切ってタスクアプリを追加開発する。:ファイルアップロード機能追加

前回までの概要

前回まででタスク管理アプリの大枠作成、ブラッシュアップをしました。
今回はファイルアップロード機能の追加を行います。

プロンプト

タスク修正画面にファイルをアップロードできるように修正してください。
項目はDatagrid等、直接の操作は出来ずReadOnlyとし、後述するボタンでのみ操作可能とする。
カラムは以下
 カラム:No,ファイル名
項目下部に追加、削除ボタンを作成

回答

実装方針

タスク編集画面へ:

添付ファイル管理

を追加します。

仕様

項目内容
表示DataGridView
編集ReadOnly
追加ボタンのみ
削除ボタンのみ
カラムNo, ファイル名
実体ファイルパス保持
複数追加対応
DragDrop今回なし

完成イメージ

┌──────────────────────┐
│ 添付ファイル         │
├────┬─────────────────┤
│No  │ ファイル名      │
├────┼─────────────────┤
│1   │ test.xlsx       │
│2   │ spec.docx       │
└────┴─────────────────┘

[追加] [削除]

前提

TaskItem.cs に既に:

public List<string> Attachments
{
    get;
    set;
} = new();

が存在する前提。

1. TaskEditForm.Designer.cs 修正

フィールド追加

private Label lblAttachments;

private DataGridView dgvAttachments;

private Button btnAddAttachment;

private Button btnRemoveAttachment;

InitializeComponent() 追加

lblAttachments =
    new Label();

lblAttachments.Text =
    "添付ファイル";

lblAttachments.Location =
    new Point(20, 620);

lblAttachments.AutoSize = true;

DataGridView

dgvAttachments =
    new DataGridView();

dgvAttachments.Location =
    new Point(20, 650);

dgvAttachments.Size =
    new Size(500, 180);

dgvAttachments.ReadOnly = true;

dgvAttachments.AllowUserToAddRows =
    false;

dgvAttachments.AllowUserToDeleteRows =
    false;

dgvAttachments.MultiSelect =
    false;

dgvAttachments.SelectionMode =
    DataGridViewSelectionMode
        .FullRowSelect;

dgvAttachments.RowHeadersVisible =
    false;

dgvAttachments.AutoGenerateColumns =
    false;

カラム追加

var colNo =
    new DataGridViewTextBoxColumn();

colNo.Name = "colAttachNo";

colNo.HeaderText = "No";

colNo.Width = 60;
var colFileName =
    new DataGridViewTextBoxColumn();

colFileName.Name =
    "colAttachFileName";

colFileName.HeaderText =
    "ファイル名";

colFileName.AutoSizeMode =
    DataGridViewAutoSizeColumnMode
        .Fill;

カラム追加

dgvAttachments.Columns.Add(
    colNo);

dgvAttachments.Columns.Add(
    colFileName);

追加ボタン

btnAddAttachment =
    new Button();

btnAddAttachment.Text =
    "追加";

btnAddAttachment.Location =
    new Point(20, 840);

btnAddAttachment.Size =
    new Size(100, 35);

削除ボタン

btnRemoveAttachment =
    new Button();

btnRemoveAttachment.Text =
    "削除";

btnRemoveAttachment.Location =
    new Point(140, 840);

btnRemoveAttachment.Size =
    new Size(100, 35);

Controls追加

Controls.Add(lblAttachments);

Controls.Add(dgvAttachments);

Controls.Add(btnAddAttachment);

Controls.Add(btnRemoveAttachment);

Formサイズ調整

修正前

ClientSize =
    new Size(900, 700);

修正後

ClientSize =
    new Size(900, 900);

2. TaskEditForm.cs 修正

using追加

using System.IO;

コンストラクタ追加

btnAddAttachment.Click +=
    btnAddAttachment_Click;

btnRemoveAttachment.Click +=
    btnRemoveAttachment_Click;

3. 添付一覧読込追加

LoadTask() 内追加

LoadAttachments();

新規追加

private void LoadAttachments()
{
    dgvAttachments.Rows.Clear();

    for (int i = 0;
         i < _task.Attachments.Count;
         i++)
    {
        string path =
            _task.Attachments[i];

        int row =
            dgvAttachments.Rows.Add();

        dgvAttachments.Rows[row]
            .Cells["colAttachNo"]
            .Value = i + 1;

        dgvAttachments.Rows[row]
            .Cells["colAttachFileName"]
            .Value =
                Path.GetFileName(path);

        dgvAttachments.Rows[row]
            .Tag = path;
    }
}

4. 追加処理

private void btnAddAttachment_Click(
    object? sender,
    EventArgs e)
{
    using var dialog =
        new OpenFileDialog();

    dialog.Multiselect = true;

    if (dialog.ShowDialog()
        != DialogResult.OK)
    {
        return;
    }

    foreach (string file
        in dialog.FileNames)
    {
        if (!_task.Attachments
            .Contains(file))
        {
            _task.Attachments
                .Add(file);
        }
    }

    LoadAttachments();
}

5. 削除処理

private void btnRemoveAttachment_Click(
    object? sender,
    EventArgs e)
{
    if (dgvAttachments
        .SelectedRows.Count
        == 0)
    {
        return;
    }

    var row =
        dgvAttachments
            .SelectedRows[0];

    string? path =
        row.Tag?.ToString();

    if (string.IsNullOrEmpty(path))
    {
        return;
    }

    var result =
        MessageBox.Show(
            "選択した添付ファイルを削除しますか?",
            "確認",
            MessageBoxButtons.YesNo,
            MessageBoxIcon.Question);

    if (result
        != DialogResult.Yes)
    {
        return;
    }

    _task.Attachments
        .Remove(path);

    LoadAttachments();
}

6. 保存処理

既に:

_task.Attachments

へ反映されるため追加不要。

7. JSON保存確認

TaskItem.json保存対象確認。

必須

public List<string> Attachments
{
    get;
    set;
} = new();

8. CSV/Excel出力反映

既に:

string.Join(";",
    task.Attachments)

があるならOK。

さらにおすすめ

かなり実務向けになります。

機能効果
ダブルクリックで開くUX
ファイル存在チェック安全性
DragDrop高UX
添付日管理
添付者監査
プレビュー実務向け
相対パス化配布向け
コピー保存安全
アイコン表示視認性
PDFプレビュー高機能

特におすすめ

次は:

ダブルクリックでファイルを開く

です。

かなり便利になります。

追加コード

dgvAttachments.CellDoubleClick +=
    dgvAttachments_CellDoubleClick;
private void dgvAttachments_CellDoubleClick(
    object? sender,
    DataGridViewCellEventArgs e)
{
    if (e.RowIndex < 0)
    {
        return;
    }

    string? path =
        dgvAttachments
            .Rows[e.RowIndex]
            .Tag?
            .ToString();

    if (string.IsNullOrEmpty(path))
    {
        return;
    }

    if (!File.Exists(path))
    {
        MessageBox.Show(
            "ファイルが存在しません。");

        return;
    }

    Process.Start(
        new ProcessStartInfo
        {
            FileName = path,
            UseShellExecute = true
        });
}

実装、起動確認

まとめ

次回もAIと相談しつつ機能の追加をしていく予定です。