using System.Windows.Forms;
using System.Collections.Generic;
using System.Linq;
namespace ChatworkBulkSender.Utils
{
/// <summary>
/// マスタ画面のTabIndex(フォーカス順)を設定するヘルパークラス
/// </summary>
public static class TabIndexHelper
{
/// <summary>
/// マスタ検索画面のTabIndexを設定
/// </summary>
public static void SetMasterScreenTabOrder(Form form,
Control searchBoxControl,
Control dgvControl,
Control btnControl)
{
// nullチェック
if (form == null || searchBoxControl == null ||
dgvControl == null || btnControl == null) return;
// 検索ボックス内のコントロールにTabIndexを設定
SetSearchBoxTabOrder(searchBoxControl, 0);
// DataGridViewのTabIndexを設定
SetDataGridViewTabOrder(dgvControl, 100);
// ボタンコントロールのTabIndexを設定
SetButtonTabOrder(btnControl, 200);
}
/// <summary>
/// 検索ボックス内のコントロールのTabIndexを設定
/// </summary>
private static void SetSearchBoxTabOrder(Control searchBoxControl, int startIndex)
{
var controls = GetAllControls(searchBoxControl)
.Where(c => c is TextBox || c is ComboBox || c is CheckBox || c is Button)
.Where(c => c.Visible)
.OrderBy(c => c.Location.Y)
.ThenBy(c => c.Location.X)
.ToList();
int tabIndex = startIndex;
foreach (var control in controls)
{
control.TabIndex = tabIndex++;
control.TabStop = true;
}
}
/// <summary>
/// DataGridViewのTabIndexを設定
/// </summary>
private static void SetDataGridViewTabOrder(Control dgvControl, int tabIndex)
{
var dgv = FindControl<DataGridView>(dgvControl);
if (dgv != null)
{
dgv.TabIndex = tabIndex;
dgv.TabStop = true;
}
}
/// <summary>
/// ボタンコントロールのTabIndexを設定
/// </summary>
private static void SetButtonTabOrder(Control btnControl, int startIndex)
{
var buttons = GetAllControls(btnControl)
.Where(c => c is Button)
.Where(c => c.Visible)
.OrderBy(c => c.Location.X)
.ToList();
int tabIndex = startIndex;
foreach (var button in buttons)
{
button.TabIndex = tabIndex++;
button.TabStop = true;
}
}
/// <summary>
/// コントロール内のすべての子コントロールを取得
/// </summary>
private static IEnumerable<Control> GetAllControls(Control parent)
{
var controls = new List<Control>();
foreach (Control control in parent.Controls)
{
controls.Add(control);
controls.AddRange(GetAllControls(control));
}
return controls;
}
/// <summary>
/// 特定の型のコントロールを検索
/// </summary>
private static T FindControl<T>(Control parent) where T : Control
{
foreach (Control control in parent.Controls)
{
if (control is T typedControl)
{
return typedControl;
}
T found = FindControl<T>(control);
if (found != null) return found;
}
return null;
}
/// <summary>
/// 個別編集画面のTabIndexを設定
/// </summary>
public static void SetIndividualEditScreenTabOrder(Form form)
{
// nullチェック
if (form == null) return;
// すべてのコントロールを位置でソート
var controls = GetAllControls(form)
.Where(c => c is TextBox || c is ComboBox || c is CheckBox ||
c is RadioButton || c is Button || c is DataGridView)
.Where(c => c.Visible) // 表示されているコントロールのみ
.OrderBy(c => c.Location.Y)
.ThenBy(c => c.Location.X)
.ToList();
// TabIndexを設定
int tabIndex = 0;
foreach (var control in controls)
{
control.TabIndex = tabIndex++;
control.TabStop = true;
// 読み取り専用のテキストボックスも Tab で移動可能にする
if (control is TextBox textBox && textBox.ReadOnly)
{
textBox.TabStop = true;
}
}
}
/// <summary>
/// 送信者情報マスタ画面のTabIndexを設定
/// </summary>
public static void SetSenderMasterTabOrder(Form form, Control senderInfoControl)
{
// nullチェック
if (form == null || senderInfoControl == null) return;
// 送信者情報コントロール内のコントロールを位置でソート
var controls = GetAllControls(senderInfoControl)
.Where(c => c is TextBox || c is Button)
.Where(c => c.Visible)
.OrderBy(c => c.Location.Y)
.ThenBy(c => c.Location.X)
.ToList();
// TabIndexを設定
int tabIndex = 0;
foreach (var control in controls)
{
control.TabIndex = tabIndex++;
control.TabStop = true;
}
}
}
}