UserControls/SendHistoryDgvControl.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using ChatworkBulkSender.Daos;
using ChatworkBulkSender.Dtos;
using ChatworkBulkSender.Forms;
using ChatworkBulkSender.Utils;

namespace ChatworkBulkSender.UserControls
{
    public partial class SendHistoryDgvControl : AbstractUserControl
    {
        private List<SendHistoryDto> _sendHistoryList;

        private SortableBindingListUtil<SendHistoryDto> _sortableList;

        private Dictionary<string, object> lastSearchCriteria;

        public SendHistoryDgvControl()
        {
            InitializeComponent();

            // データグリッドビューの設定
            // 行ヘッダーの格納列表示を非表示にする
            sendHistoryDgv.RowHeadersVisible = false;
            // 行の高さの変更を禁止する
            sendHistoryDgv.AllowUserToResizeRows = false;
            // 列の自動作成を無効にする
            sendHistoryDgv.AutoGenerateColumns = false;
            // 新しい行の追加を禁止にする
            sendHistoryDgv.AllowUserToAddRows = false;

            sendHistoryDgv.Columns.Clear();
        }

        private void SendHistoryDgvControl_Load(object sender, EventArgs e)
        {
            if (!IsInDesignMode())
            {
                LoadSendHistoryList();
            }
        }

        private void LoadSendHistoryList()
        {
            SendHistoryDao dao = new SendHistoryDao();

            // デフォルトは定期送信の一覧を表示
            _sendHistoryList = dao.GetSendTypeList(0);

            sendHistoryDgv.Columns.Clear();

            sendHistoryDgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;

            sendHistoryDgv.Columns.Add(new DataGridViewTextBoxColumn
            {
                DataPropertyName = nameof(SendHistoryDto.SendDt),
                Name = nameof(SendHistoryDto.SendDt),
                HeaderText = "送信日時",
                ReadOnly = true,
                SortMode = DataGridViewColumnSortMode.Programmatic
                ,
            });
            var sendDateCol = sendHistoryDgv.Columns[nameof(SendHistoryDto.SendDt)];
            sendDateCol.FillWeight = 90;

            sendHistoryDgv.Columns.Add(new DataGridViewTextBoxColumn
            {
                DataPropertyName = nameof(SendHistoryDto.PatternName),
                Name = nameof(SendHistoryDto.PatternName),
                HeaderText = "パターン名称",
                ReadOnly = true,
                SortMode = DataGridViewColumnSortMode.Programmatic
                ,
            });
            var patternIdCol = sendHistoryDgv.Columns[nameof(SendHistoryDto.PatternName)];
            patternIdCol.FillWeight = 400;

            sendHistoryDgv.Columns.Add(new DataGridViewTextBoxColumn
            {
                DataPropertyName = nameof(SendHistoryDto.SendResults),
                Name = nameof(SendHistoryDto.SendResults),
                HeaderText = "送信結果",
                ReadOnly = true,
                SortMode = DataGridViewColumnSortMode.Programmatic
                ,
            });
            var sendResultCol = sendHistoryDgv.Columns[nameof(SendHistoryDto.SendResults)];
            sendResultCol.FillWeight = 60;

            sendHistoryDgv.Columns.Add(new DataGridViewButtonColumn
            {
                Name = "BtnDetail",
                HeaderText = "詳細",
                Text = "【?】",
                UseColumnTextForButtonValue = true,
                ReadOnly = true,
                SortMode = DataGridViewColumnSortMode.NotSortable
                ,
            });
            var detailCol = sendHistoryDgv.Columns["BtnDetail"];
            detailCol.FillWeight = 38;
            detailCol.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;

            _sortableList = GetSortableColumn();

            sendHistoryDgv.DataSource = _sortableList;

        }

        private SortableBindingListUtil<SendHistoryDto> GetSortableColumn()
        {
            // ソート可能なリストを取得
            var sortableList = new SortableBindingListUtil<SendHistoryDto>(_sendHistoryList);

            return sortableList;
        }

        /// <summary>
        /// 詳細列の【?】ボタンクリック時の処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sendHistoryDgv_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            var column = sendHistoryDgv.Columns[e.ColumnIndex];

            // ヘッダー行 または 詳細列でない場合はスキップする
            if (e.RowIndex < 0 || e.ColumnIndex != 3) { return; }

            // 選択行の送信履歴データを取得
            var selectedHistory = sendHistoryDgv.Rows[e.RowIndex].DataBoundItem as SendHistoryDto;
            if (selectedHistory == null)
            {
                MessageBoxUtil.ShowErr("選択された送信履歴情報が取得できませんでした。", "エラー");
                return;
            }

            // 送信履歴詳細画面に選択したデータを渡す
            T_SendHistoryDetail sendHistoryDetail = new T_SendHistoryDetail(selectedHistory);

            sendHistoryDetail.Owner = this.ParentForm;

            this.ParentForm.Hide();

            sendHistoryDetail.FormClosed += (s, args) =>
            {
                // 親フォームを表示
                if (this.ParentForm != null && !this.ParentForm.Visible)
                {
                    this.ParentForm.Show();
                    this.ParentForm.BringToFront();
                }

                if (!IsInDesignMode())
                {
                    LoadSendHistoryList();
                }
            };

            sendHistoryDetail.Show();

        }

        /// <summary>
        /// ヘッダーをダブルクリック時に対象列を中心としてソート処理を行う。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sendHistoryDgv_ColumnHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            // ヘッダー行 かつ 番号0、1、2の列はソート処理を行う
            if (e.RowIndex == -1 && e.ColumnIndex >= 0 && e.ColumnIndex < 3)
            {
                // 対象列を取得する
                var column = sendHistoryDgv.Columns[e.ColumnIndex];

                // 対象列プロパティ名を取得する
                var propertyName = column.DataPropertyName;

                // 対象列プロパティ名からプロパティ情報を取得する
                var pd = TypeDescriptor.GetProperties(typeof(SendHistoryDto))[propertyName];

                // ソート処理へ
                _sortableList.ApplySort(pd);
            }
        }

        /// <summary>
        /// 検索処理
        /// </summary>
        public void Search(Dictionary<string, object> criteria)
        {
            lastSearchCriteria = criteria ?? new Dictionary<string, object>();

            SendHistoryDao dao = new SendHistoryDao();

            // 送信タイプで基本のリストを取得
            int sendType = 0; // デフォルトは定期送信
            if (criteria.ContainsKey("SendType"))
            {
                sendType = Convert.ToInt32(criteria["SendType"]);
            }

            _sendHistoryList = dao.GetSendTypeList(sendType);

            // フィルタリング処理
            var filteredList = _sendHistoryList.AsEnumerable();

            // 管理番号でフィルタ
            if (criteria.ContainsKey("ManagementNumber") && !string.IsNullOrWhiteSpace(criteria["ManagementNumber"].ToString()))
            {
                string mgmtNumber = criteria["ManagementNumber"].ToString();
                // 送信履歴詳細から管理番号で検索する必要があるため、今回は簡易的にスキップ
                // TODO: 詳細検索の実装が必要な場合は、SendHistoryDetailDaoから検索する
            }

            // パターン名称でフィルタ
            if (criteria.ContainsKey("PatternName") && !string.IsNullOrWhiteSpace(criteria["PatternName"].ToString()))
            {
                string patternName = criteria["PatternName"].ToString();
                filteredList = filteredList.Where(h => h.PatternName != null && h.PatternName.Contains(patternName));
            }

            // 顧客名でフィルタ
            if (criteria.ContainsKey("CustomerName") && !string.IsNullOrWhiteSpace(criteria["CustomerName"].ToString()))
            {
                string customerName = criteria["CustomerName"].ToString();
                // 送信履歴詳細から顧客名で検索する必要があるため、今回は簡易的にスキップ
                // TODO: 詳細検索の実装が必要な場合は、SendHistoryDetailDaoから検索する
            }

            // 送信日時(開始)でフィルタ
            if (criteria.ContainsKey("StartDate") && criteria["StartDate"] is DateTime startDate)
            {
                filteredList = filteredList.Where(h => h.SendDt >= startDate);
            }

            // 送信日時(終了)でフィルタ
            if (criteria.ContainsKey("EndDate") && criteria["EndDate"] is DateTime endDate)
            {
                filteredList = filteredList.Where(h => h.SendDt <= endDate);
            }

            _sendHistoryList = filteredList.ToList();

            // ソート可能リストを更新
            _sortableList = GetSortableColumn();
            sendHistoryDgv.DataSource = _sortableList;
        }
    }
}