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;
using ChatworkBulkSender.Utils;
namespace ChatworkBulkSender.UserControls
{
public partial class HistorySearchBoxControl : UserControl
{
public event EventHandler<Dictionary<string, object>> SearchRequested;
private int _pnlSearchCurrentX;
// エラー表示用ツールチップ
private ToolTip errorToolTip = new ToolTip();
// 日付が設定されているかどうかを追跡するフラグ
private bool _startDateSet = false;
private bool _endDateSet = false;
public HistorySearchBoxControl()
{
InitializeComponent();
_pnlSearchCurrentX = panelSearchBox.Width;
// デフォルト表示は空文字
dateTimePickerStart.CustomFormat = " ";
dateTimePickerEnd.CustomFormat = " ";
rdoScheduleSendSelection.Checked = true;
// 検索ボタンのイベントハンドラを設定
btnSearch.Click += BtnSearch_Click;
// 管理番号テキストボックスのイベントハンドラを設定
mgmtNumberTxtBox.TextChanged += MgmtNumberTxtBox_TextChanged;
mgmtNumberTxtBox.KeyPress += MgmtNumberTxtBox_KeyPress;
// DateTimePickerのイベントハンドラを設定
dateTimePickerStart.KeyDown += DateTimePickerStart_KeyDown;
dateTimePickerEnd.KeyDown += DateTimePickerEnd_KeyDown;
dateTimePickerStart.CloseUp += DateTimePickerStart_CloseUp;
dateTimePickerEnd.CloseUp += DateTimePickerEnd_CloseUp;
dateTimePickerStart.KeyPress += DateTimePickerStart_KeyPress;
dateTimePickerEnd.KeyPress += DateTimePickerEnd_KeyPress;
// 各テキストボックスの最大文字数を設定
mgmtNumberTxtBox.MaxLength = 10; // 管理番号は10桁まで
PattrernNameTxtBox.MaxLength = 50; // パターン名称は50文字まで
customerNameTxtBox.MaxLength = 100; // 顧客名は100文字まで
// Dockを使用して親パネル全体を使用
this.Dock = DockStyle.Fill;
}
/// <summary>
/// 選択時に日付を西暦/月/日のフォーマットで表示する。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dateTimePickerStart_ValueChanged(object sender, EventArgs e)
{
dateTimePickerStart.CustomFormat = "yyyy/MM/dd";
_startDateSet = true;
}
/// <summary>
/// 選択時に日付を西暦/月/日のフォーマットで表示する。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dateTimePickerEnd_ValueChanged(object sender, EventArgs e)
{
dateTimePickerEnd.CustomFormat = "yyyy/MM/dd";
_endDateSet = true;
}
private void panelSearchBox_Resize(object sender, EventArgs e)
{
int Width = _pnlSearchCurrentX - panelSearchBox.Width;
customerNameTxtBox.Width -= Width;
}
/// <summary>
/// 開始日付のKeyDownイベントハンドラ
/// DeleteキーまたはBackspaceキーで日付をクリアする
/// </summary>
private void DateTimePickerStart_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back)
{
dateTimePickerStart.CustomFormat = " ";
_startDateSet = false;
e.Handled = true;
e.SuppressKeyPress = true;
}
}
/// <summary>
/// 終了日付のKeyDownイベントハンドラ
/// DeleteキーまたはBackspaceキーで日付をクリアする
/// </summary>
private void DateTimePickerEnd_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back)
{
dateTimePickerEnd.CustomFormat = " ";
_endDateSet = false;
e.Handled = true;
e.SuppressKeyPress = true;
}
}
/// <summary>
/// 開始日付のCloseUpイベントハンドラ
/// カレンダーから日付を選択したときの処理
/// </summary>
private void DateTimePickerStart_CloseUp(object sender, EventArgs e)
{
dateTimePickerStart.CustomFormat = "yyyy/MM/dd";
_startDateSet = true;
}
/// <summary>
/// 終了日付のCloseUpイベントハンドラ
/// カレンダーから日付を選択したときの処理
/// </summary>
private void DateTimePickerEnd_CloseUp(object sender, EventArgs e)
{
dateTimePickerEnd.CustomFormat = "yyyy/MM/dd";
_endDateSet = true;
}
/// <summary>
/// 開始日付のKeyPressイベントハンドラ
/// 何か入力があったら日付フォーマットを有効化
/// </summary>
private void DateTimePickerStart_KeyPress(object sender, KeyPressEventArgs e)
{
// 数字が入力されたら日付フォーマットを有効化
if (char.IsDigit(e.KeyChar) && !_startDateSet)
{
dateTimePickerStart.CustomFormat = "yyyy/MM/dd";
_startDateSet = true;
}
}
/// <summary>
/// 終了日付のKeyPressイベントハンドラ
/// 何か入力があったら日付フォーマットを有効化
/// </summary>
private void DateTimePickerEnd_KeyPress(object sender, KeyPressEventArgs e)
{
// 数字が入力されたら日付フォーマットを有効化
if (char.IsDigit(e.KeyChar) && !_endDateSet)
{
dateTimePickerEnd.CustomFormat = "yyyy/MM/dd";
_endDateSet = true;
}
}
/// <summary>
/// 管理番号テキストボックスのKeyPressイベントハンドラ
/// </summary>
private void MgmtNumberTxtBox_KeyPress(object sender, KeyPressEventArgs e)
{
// バックスペース、Delete、Ctrl+V は許可
if (e.KeyChar == '\b' || char.IsControl(e.KeyChar))
{
return;
}
// 数字以外の入力時
if (!char.IsDigit(e.KeyChar))
{
e.Handled = true;
// ツールチップでエラーメッセージを表示
errorToolTip.Show("半角数字のみ入力可能です", mgmtNumberTxtBox, 0, -25, 2000);
}
}
/// <summary>
/// 管理番号テキストボックスのTextChangedイベントハンドラ
/// </summary>
private void MgmtNumberTxtBox_TextChanged(object sender, EventArgs e)
{
// 先頭のゼロを削除する処理
if (!string.IsNullOrWhiteSpace(mgmtNumberTxtBox.Text))
{
string text = mgmtNumberTxtBox.Text;
// 先頭の0を削除(001 → 1)
if (text.Length > 1 && text.StartsWith("0"))
{
if (int.TryParse(text, out int number))
{
mgmtNumberTxtBox.Text = number.ToString();
// カーソルを末尾に移動
mgmtNumberTxtBox.SelectionStart = mgmtNumberTxtBox.Text.Length;
}
}
// バリデーション
if (!ValidationHelperUtil.IsValidManagementNumber(mgmtNumberTxtBox.Text))
{
// 背景色を薄い赤にして視覚的にエラーを示す
mgmtNumberTxtBox.BackColor = Color.FromArgb(255, 230, 230);
errorToolTip.Show(ValidationHelperUtil.GetManagementNumberFormatErrorMessage(),
mgmtNumberTxtBox, 0, -25, 3000);
}
else
{
// 正常な場合は背景色を元に戻す
mgmtNumberTxtBox.BackColor = SystemColors.Window;
errorToolTip.Hide(mgmtNumberTxtBox);
}
}
else
{
// 空の場合も背景色を元に戻す
mgmtNumberTxtBox.BackColor = SystemColors.Window;
errorToolTip.Hide(mgmtNumberTxtBox);
}
}
/// <summary>
/// 検索ボタンクリック
/// </summary>
private void BtnSearch_Click(object sender, EventArgs e)
{
// バリデーション実行
string validationError;
if (!ValidateSearchCriteria(out validationError))
{
MessageBox.Show(validationError, "入力エラー",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
var criteria = GetSearchCriteria();
SearchRequested?.Invoke(this, criteria);
}
/// <summary>
/// 検索条件を取得
/// </summary>
private Dictionary<string, object> GetSearchCriteria()
{
var criteria = new Dictionary<string, object>();
// 管理番号
if (!string.IsNullOrWhiteSpace(mgmtNumberTxtBox.Text))
{
criteria["ManagementNumber"] = mgmtNumberTxtBox.Text.Trim();
}
// パターン名称
if (!string.IsNullOrWhiteSpace(PattrernNameTxtBox.Text))
{
criteria["PatternName"] = PattrernNameTxtBox.Text.Trim();
}
// 顧客名
if (!string.IsNullOrWhiteSpace(customerNameTxtBox.Text))
{
criteria["CustomerName"] = customerNameTxtBox.Text.Trim();
}
// 送信日時(開始)
if (_startDateSet)
{
criteria["StartDate"] = dateTimePickerStart.Value.Date;
}
// 送信日時(終了)
if (_endDateSet)
{
criteria["EndDate"] = dateTimePickerEnd.Value.Date.AddDays(1).AddSeconds(-1);
}
// 送信タイプ
if (rdoScheduleSendSelection.Checked)
{
criteria["SendType"] = 0; // 定期送信
}
else if (rdoManualSendSelection.Checked)
{
criteria["SendType"] = 1; // 不定期送信
}
return criteria;
}
/// <summary>
/// 検索条件のバリデーション
/// </summary>
/// <param name="errorMessage">エラーメッセージ</param>
/// <returns>バリデーション成功時はtrue</returns>
private bool ValidateSearchCriteria(out string errorMessage)
{
errorMessage = string.Empty;
var errors = new List<string>();
// 管理番号のバリデーション
if (!string.IsNullOrWhiteSpace(mgmtNumberTxtBox.Text))
{
if (!ValidationHelperUtil.IsValidManagementNumber(mgmtNumberTxtBox.Text))
{
errors.Add(ValidationHelperUtil.GetManagementNumberFormatErrorMessage());
}
}
// 日付範囲のバリデーション
if (_startDateSet && _endDateSet)
{
if (dateTimePickerStart.Value.Date > dateTimePickerEnd.Value.Date)
{
errors.Add("送信日時の開始日は終了日以前の日付を指定してください。");
}
}
if (errors.Any())
{
errorMessage = string.Join("\n", errors);
return false;
}
return true;
}
}
}