Files
HLib/Forms/Controls/PoiMainForm.cs
T
2026-06-01 13:23:34 +09:00

589 lines
24 KiB
C#

using DocumentFormat.OpenXml.VariantTypes;
using KssSmaPlaLib.Ini;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Windows.Media.Streaming.Adaptive;
namespace KssSmaPlaLib.Forms.Controls
{
/// <summary>
/// Poiメインフォーム
/// </summary>
public class PoiMainForm : Form
{
protected Label TitleLabel;
protected PoiDgv MainDgv;
protected ContextMenuStrip MainContextMenu;
protected ToolStripMenuItem TitleVisibleCheckMenu;
private ToolStripMenuItem _versionMenu;
private NumericUpDown _titleLabelYohakuHorizonNumeric = new NumericUpDown { Width = 60 };
private NumericUpDown _titleLabelYohakuVarticalNumeric = new NumericUpDown { Width = 60 };
// 👇遅延書き込みしようかと思ったがやめた!
//private Timer _saveDelayTimer = new Timer { Interval = 1000 };
private string _title = string.Empty;
/// <summary>
/// コンストラクタ
/// </summary>
public PoiMainForm(string title = "", string name = "")
{
// Name
this.Name = string.IsNullOrEmpty(name) ? this.GetType().Name : name;
// タイトル
_title = string.IsNullOrEmpty(title) ? this.Name : title;
this.Text = _title;
// フォームイベント
this.Load += PoiMainForm_Load;
this.FormClosing += PoiMainForm_FormClosing;
// コントロールの生成と配置
TitleLabel = new Label
{
Name = "TitleLabel",
AutoSize = true,
Dock = DockStyle.Top,
Text = "サンプルです💖",
};
TitleLabel.Padding = new Padding(20, 5, 8, 20);
MainDgv = new PoiDgv
{
Name = "MainDgv",
Dock = DockStyle.Fill
};
MainContextMenu = new ContextMenuStrip
{
Name = "MainContextMenu",
};
this.ContextMenuStrip = MainContextMenu;
this.Controls.Add(MainDgv);
this.Controls.Add(TitleLabel);
// デフォルトのメニュー項目登録
CreateDefaultMenu();
DgvHelper.DgvLoadFontFromIni(MainDgv);
//ContextMenuHelper.MenuCheckBoxItemLoad(this, TitleVisibleCheckMenu);
TitleLabel.Visible = TitleVisibleCheckMenu.Checked;
ContextMenuHelper.SetControlFont(this, TitleLabel);
ContextMenuHelper.DispVersion(_versionMenu);
// ソート無効
foreach (DataGridViewColumn column in MainDgv.Columns) column.SortMode = DataGridViewColumnSortMode.NotSortable;
//// 日の列はセンタリング
//for (var day = 1; day <= 31; day++) MainDgv.Columns[$"ColDay{day}"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
// TOTAL列は右寄せ
//MainDgv.Columns["ColTotal"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
// ヘッダ行のデザインはOSのデザインを反映させる機能を解除
MainDgv.EnableHeadersVisualStyles = false;
// 👇やろうかと思ったけどやめた!
//// 遅延書き込みタイマー
//_saveDelayTimer.Tick += (s, e) =>
//{
// _saveDelayTimer.Stop(); // タイマーを止める
// // 👑 ここでINIファイルへの書き込みを実行!
// // スピンボタン連打が「止まってから1秒後」に1回だけ綺麗に保存されます。
// aaaaaaa
//};
//LoadDataAsync();
// タイトル文字列設定
//TitleLabel.Text = GetTitle();
}
/// <summary>
/// フォームロード時
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="NotImplementedException"></exception>
private void PoiMainForm_Load(object sender, EventArgs e)
{
FormHelper.LoadFormBounds(this);
DgvHelper.DgvLoadFontFromIni(MainDgv);
DgvHelper.DgvLoadColWidth(MainDgv);
DgvHelper.DgvLoadHeaderHeight(MainDgv);
DgvHelper.DgvLoadColVisible(MainDgv);
DgvHelper.DgvLoadColDisplayIndex(MainDgv);
DgvHelper.DgvLoadColFrozen(MainDgv);
DgvHelper.DgvSetHeaderBackColorFromIni(this, MainDgv);
//DgvHelper.DgvSetHeaderBackColorFromIniWithNameMatch(this, MainDgv, "ColDay*", INI_KEY_HEADER_DAY_COLUMN_BACK_COLOR);
// 👇これはLoadでやらないと、子で作ってるメニューアイテムに反映されない!
ContextMenuHelper.LoadAllMenuStates(this, MainContextMenu);
ContextMenuHelper.SetFont(this, MainContextMenu);
var vertical =
int.TryParse(
IniHelper.ReadValue(null, this.Name, _titleLabelYohakuVarticalNumeric.Name, "0"),
out var intVal) ? intVal : 0;
var horizon =
int.TryParse(
IniHelper.ReadValue(null, this.Name, _titleLabelYohakuHorizonNumeric.Name, "0"),
out intVal) ? intVal : 0;
TitleLabel.Padding = new Padding(horizon, vertical, horizon, vertical);
}
/// <summary>
/// フォーム閉じるとき
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="NotImplementedException"></exception>
private void PoiMainForm_FormClosing(object sender, FormClosingEventArgs e)
{
FormHelper.SaveFormBounds(this);
DgvHelper.DgvSaveFontToIni(MainDgv);
DgvHelper.DgvSaveColWidth(MainDgv);
DgvHelper.DgvSaveHeaderHeight(MainDgv);
DgvHelper.DgvSaveColVisible(MainDgv);
DgvHelper.DgvSaveColDisplayIndex(MainDgv);
DgvHelper.DgvSaveColFrozen(MainDgv);
IniHelper.WriteValue(
null, this.Name,
_titleLabelYohakuHorizonNumeric.Name,
_titleLabelYohakuHorizonNumeric.Value.ToString());
IniHelper.WriteValue(
null, this.Name,
_titleLabelYohakuVarticalNumeric.Name,
_titleLabelYohakuVarticalNumeric.Value.ToString());
}
/// <summary>
/// デフォルトのメニュー項目(表示設定など)を作成
/// </summary>
private void CreateDefaultMenu()
{
// 仕切り線
MainContextMenu.Items.Add(new ToolStripSeparator());
// 表示設定(親)
var hyojiSetteiMenu = new ToolStripMenuItem()
{
Name = "HyojiSetteiMenu",
Text = "表示設定",
};
MainContextMenu.Items.Add(hyojiSetteiMenu);
// メニューのフォント(クリック動作)
var menuFontMenu = new ToolStripMenuItem()
{
Name = "MenuFontMenu",
Text = "メニューのフォント...",
};
menuFontMenu.Click += (s, e)=>
{
ContextMenuHelper.SelectMenuFont(this, MainContextMenu);
};
hyojiSetteiMenu.DropDownItems.Add(menuFontMenu);
// グリッドメニュー(親)
var gridMenu = new ToolStripMenuItem()
{
Name = "GridMenu",
Text = "グリッド",
};
hyojiSetteiMenu.DropDownItems.Add(gridMenu);
// グリッドフォントメニュー(クリック動作)
var gridFontMenu = new ToolStripMenuItem()
{
Name = "GridFontMenu",
Text = "フォント...",
};
gridFontMenu.Click += (s, e) =>
{
DgvHelper.DgvSelectFont(this, MainDgv);
};
gridMenu.DropDownItems.Add(gridFontMenu);
// グリッド列非表示メニュー(クリック動作)
var gridColumnDisabledMenu = new ToolStripMenuItem()
{
Name = "GridColumnDisabledMenu",
Text = "この列を非表示にする",
};
gridColumnDisabledMenu.Click += (s, e) =>
{
if (MainDgv.CurrentCell is null) return;
MainDgv.Columns[MainDgv.CurrentCell.ColumnIndex].Visible = false;
};
gridMenu.DropDownItems.Add(gridColumnDisabledMenu);
// グリッド列再表示メニュー(クリック動作)
var gridColumnRedispMenu = new ToolStripMenuItem()
{
Name = "GridColumnRedispMenu",
Text = "列の再表示",
};
gridColumnRedispMenu.Click += (s, e) =>
{
DgvHelper.DgvRedispAllColumn(MainDgv);
};
gridMenu.DropDownItems.Add(gridColumnRedispMenu);
// グリッド列幅自動調整メニュー(クリック動作)
var columnWidthAutoAdjustMenu = new ToolStripMenuItem()
{
Name = "ColumnWidthAutoAdjustMenu",
Text = "列幅の自動調整",
};
columnWidthAutoAdjustMenu.Click += (s, e) =>
{
DgvHelper.DgvColumnWidthAutoAdjust(MainDgv);
};
gridMenu.DropDownItems.Add(columnWidthAutoAdjustMenu);
// グリッド列固定メニュー(クリック動作)
var gridColumnFixMenu = new ToolStripMenuItem()
{
Name = "GridColumnFixMenu",
Text = "列固定",
};
gridColumnFixMenu.Click += (s, e) =>
{
DgvHelper.DgvColumnFix(MainDgv);
};
gridMenu.DropDownItems.Add(gridColumnFixMenu);
// グリッド列固定解除メニュー(クリック動作)
var gridColumnFixKaijoMenu = new ToolStripMenuItem()
{
Name = "GridColumnFixKaijoMenu",
Text = "列固定解除",
};
gridColumnFixKaijoMenu.Click += (s, e) =>
{
DgvHelper.DgvColumnFixKaijo(MainDgv);
};
gridMenu.DropDownItems.Add(gridColumnFixKaijoMenu);
// グリッドのヘッダ(親)
//this.GridHeaderMenu});
var gridHeaderMenu = new ToolStripMenuItem()
{
Name = "GridHeaderMenu",
Text = "ヘッダ",
};
gridMenu.DropDownItems.Add(gridHeaderMenu);
// グリッドヘッダ背景色(クリック動作)
var gridHeaderBackColorMenu = new ToolStripMenuItem()
{
Name = "GridHeaderBackColorMenu",
Text = "ヘッダ背景色...",
};
gridHeaderBackColorMenu.Click += (s, e) =>
{
DgvHelper.DgvSelectHeaderBackColor(this, MainDgv);
};
gridHeaderMenu.DropDownItems.Add(gridHeaderBackColorMenu);
// グリッドヘッダの日の背景色(クリック動作)
var gridHeaderDayBackColorMenu = new ToolStripMenuItem()
{
Name = "GridHeaderDayBackColorMenu",
Text = "日の背景色...",
Enabled = false, // デフォルトは非活性
};
gridHeaderDayBackColorMenu.Click += (s, e) =>
{
DgvHelper.DgvSelectHeaderBackColorWithNameMatch(this, MainDgv, "ColDay*", gridHeaderDayBackColorMenu.Name);
};
gridHeaderMenu.DropDownItems.Add(gridHeaderDayBackColorMenu);
// グリッドヘッダの非稼働日の背景色(クリック動作)
var gridHeaderHikadobiBackColorMenu = new ToolStripMenuItem()
{
Name = "GridHeaderHikadobiBackColorMenu",
Text = "非稼働日の背景色...",
Enabled = false, // デフォルトは非活性
};
gridHeaderHikadobiBackColorMenu.Click += (s, e) =>
{
// Comming soon!
MessageBox.Show(this,"カミングスーン!",this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
};
gridHeaderMenu.DropDownItems.Add(gridHeaderHikadobiBackColorMenu);
//this.GridHeaderMenu.DropDownItems.AddRange(
// new System.Windows.Forms.ToolStripItem[] {
//this.,
//this.,
//this.});
// グリッドメニューを開くときの制御
gridMenu.DropDownOpening += (s, e) =>
{
// 「この列の非表示」はアクティブセルがあるときだけ有効
gridColumnDisabledMenu.Enabled = !(MainDgv.CurrentCell is null);
// 「列の再表示」は非表示列があるときだけ有効
gridColumnRedispMenu.Enabled =
MainDgv.Columns.GetColumnCount(DataGridViewElementStates.Visible)
!= MainDgv.Columns.Count;
// 「列固定」はアクティブセルがあるときだけ有効
gridColumnFixMenu.Enabled = !(MainDgv.CurrentCell is null);
// 「列固定解除」は列固定がされているときだけ有効
gridColumnFixKaijoMenu.Enabled = MainDgv.Columns
.Cast<DataGridViewColumn>()
.Any(c => c.Frozen);
};
// タイトル(親)
var titleMenu =
new ToolStripMenuItem()
{
Name = "TitleMenu",
Text = "タイトル",
};
hyojiSetteiMenu.DropDownItems.Add(titleMenu);
// タイトル表示(チェックボックス)
TitleVisibleCheckMenu =
new ToolStripMenuItem()
{
Name = "TitleVisibleCheckMenu",
Text = "タイトル表示?",
CheckOnClick = true,
};
TitleVisibleCheckMenu.CheckedChanged += (s, e) =>
{
var mi = (ToolStripMenuItem)s;
IniHelper.WriteBoolValue(null, this.Name, mi.Name,
mi.Checked);
TitleLabel.Visible = mi.Checked;
};
titleMenu.DropDownItems.Add(TitleVisibleCheckMenu);
// タイトルフォントメニュー(クリック動作)
var titleFontMenu =
new ToolStripMenuItem()
{
Name = "TitleFontMenu",
Text = "フォント...",
};
titleFontMenu.Click += (s, e) =>
{
ContextMenuHelper.SelectControlFont(this, TitleLabel);
};
titleMenu.DropDownItems.Add(titleFontMenu);
// タイトル余白(親)
var titleYohakuMenu = new ToolStripMenuItem()
{
Name = "TitleYohakuMenu",
Text = "余白",
};
titleMenu.DropDownItems.Add(titleYohakuMenu);
// 余白設定パネル
titleYohakuMenu.DropDownItems.Add(CreateYohakuPanelMenu());
// 仕切り線
MainContextMenu.Items.Add(new ToolStripSeparator());
// バージョン表示メニュー(表示のみ)
_versionMenu =
new ToolStripMenuItem()
{
Name = "VersionMenu",
Text = "バージョン情報",
};
MainContextMenu.Items.Add(_versionMenu);
//titleMenu.DropDownItems.Add(CreateYohakuPanelMenu());
//MainContextMenu.Items.Add(CreateYohakuPanelMenu());
// 実験!✨✨✨
//// NumericUpDownを生成して設定
//NumericUpDown numericUpDown = new NumericUpDown();
//numericUpDown.Minimum = 0;
//numericUpDown.Maximum = 100;
//numericUpDown.Value = 10;
//numericUpDown.Width = 60; // メニュー内で邪魔にならない幅に調整
//// ToolStripControlHostでラップしてメニューに追加
//ToolStripControlHost host = new ToolStripControlHost(numericUpDown);
//MainContextMenu.Items.Add(host); // または menuStrip1.Items.Add(host);
}
/// <summary>
/// 余白調整パネルメニュー作成
/// </summary>
/// <returns></returns>
private ToolStripControlHost CreateYohakuPanelMenu()
{
// 1. 土台となるパネル(縦方向にコントロールを並べる)
TableLayoutPanel miniDialog = new TableLayoutPanel();
miniDialog.ColumnCount = 2; // 2列のグリッド
miniDialog.RowCount = 2; // 3; // 3行
miniDialog.AutoSize = true;
miniDialog.Padding = new Padding(10); // 周囲に余白を作ってダイアログ感を出す
miniDialog.BackColor = Color.FromArgb(240, 240, 240); // ほんのり背景色を変える
// 2. コントロール達を作成
Label lblX = new Label { Text = "横余白:", AutoSize = true, Anchor = AnchorStyles.Left };
_titleLabelYohakuHorizonNumeric = new NumericUpDown
{
Name = "TitleLabelYohakuHorizonNumeric",
Width = 60,
TextAlign = HorizontalAlignment.Right,
};
_titleLabelYohakuHorizonNumeric.ValueChanged += (sender, e) =>
{
TitleLabel.Padding = new Padding(
(int)_titleLabelYohakuHorizonNumeric.Value,
TitleLabel.Padding.Top,
(int)_titleLabelYohakuHorizonNumeric.Value,
TitleLabel.Padding.Bottom);
// 🔥🌊INI書きはFormClosingで行う!
};
Label lblY = new Label { Text = "縦余白:", AutoSize = true, Anchor = AnchorStyles.Left };
_titleLabelYohakuVarticalNumeric = new NumericUpDown
{
Name = "TitleLabelYohakuVarticalNumeric",
Width = 60,
TextAlign = HorizontalAlignment.Right,
};
_titleLabelYohakuVarticalNumeric.ValueChanged += (sender, e) =>
{
TitleLabel.Padding = new Padding(
TitleLabel.Padding.Left,
(int)_titleLabelYohakuVarticalNumeric.Value,
TitleLabel.Padding.Right,
(int)_titleLabelYohakuVarticalNumeric.Value);
// 🔥🌊INI書きはFormClosingで行う!
};
//CheckBox chkAuto = new CheckBox { Text = "自動調整", AutoSize = true };
// 3. グリッドパネルに綺麗に配置
miniDialog.Controls.Add(lblX, 0, 0);
miniDialog.Controls.Add(_titleLabelYohakuHorizonNumeric, 1, 0);
miniDialog.Controls.Add(lblY, 0, 1);
miniDialog.Controls.Add(_titleLabelYohakuVarticalNumeric, 1, 1);
//// チェックボックスは2列分ぶち抜きで配置
//miniDialog.Controls.Add(chkAuto, 0, 2);
//miniDialog.SetColumnSpan(chkAuto, 2);
// 4. メニューにホストする
//ToolStripControlHost dialogHost = new ToolStripControlHost(miniDialog);
//MainContextMenu.Items.Add(dialogHost);
// 開くときの処理
var tssh = new ToolStripControlHost(miniDialog);
tssh.OwnerChanged += (sender, e) =>
{
// 親となるメニュー(ToolStripDropDown)を取得
if (tssh.Owner is ToolStripDropDown parentMenu)
{
// 親の「開く直前イベント」に、自分のメソッドをこっそり登録する!
parentMenu.Opening -= ParentMenu_Opening; // 二重登録防止
parentMenu.Opening += ParentMenu_Opening;
}
};
return tssh;
}
/// <summary>
/// 親メニュー開くときに追加する処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ParentMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
{
//// フォントを親に合わせる(階層深いと反映されないため)
//_titleLabelYohakuHorizonNumeric.Font =
// _titleLabelYohakuVarticalNumeric.Font =
// MainContextMenu.Font;
// パネルの合わせ、再レイアウト(パネルが階層奥深くだと、なぜか反映されていなかったりする)
var parent = _titleLabelYohakuHorizonNumeric.Parent;
if (parent != null)
{
parent.Font = MainContextMenu.Font;
parent.PerformLayout();
}
// タイトルラベルの現在の余白をNumericUpDownに設定
_titleLabelYohakuHorizonNumeric.Value = TitleLabel.Padding.Left;
_titleLabelYohakuVarticalNumeric.Value = TitleLabel.Padding.Top;
}
/// <summary>
/// メニュー項目追加
/// </summary>
/// <param name="text"></param>
/// <param name="name"></param>
/// <param name="defaultValue"></param>
/// <param name="onCheckedChanged"></param>
/// <returns></returns>
protected ToolStripMenuItem AddCheckMenuItem(
int index,
string text,
string name,
bool defaultValue,
Action<bool> onCheckedChanged = null)
{
var item = new ToolStripMenuItem(text);
// チェックボックスとして機能する
item.CheckOnClick = true;
item.Name = name;
// 3. CheckedChanged イベントをここで一括で仕込む!
item.CheckedChanged += (sender, e) =>
{
var mi = (ToolStripMenuItem)sender;
// チェック値をINI保存
IniHelper.WriteBoolValue(null, this.Name, mi.Name, mi.Checked);
// イベントプロシージャ(あるとき)
onCheckedChanged?.Invoke(mi.Checked);
};
MainContextMenu.Items.Insert(index, item);
return item;
}
public enum PoiAlign
{
Left,
Right,
Center,
}
private DataGridViewContentAlignment GetDgvAlign(PoiAlign align)
{
switch (align)
{
case PoiAlign.Left: return DataGridViewContentAlignment.MiddleLeft;
case PoiAlign.Center: return DataGridViewContentAlignment.MiddleCenter;
case PoiAlign.Right: return DataGridViewContentAlignment.MiddleRight;
default: return DataGridViewContentAlignment.MiddleLeft;
}
}
/// <summary>
/// 列追加
/// </summary>
/// <param name="name"></param>
/// <param name="text"></param>
/// <param name="align"></param>
protected void AddColumn(string name, string text, PoiAlign align = PoiAlign.Left)
{
var col = new DataGridViewTextBoxColumn()
{
Name = name,
HeaderText = text,
ReadOnly = true,
};
col.DefaultCellStyle.Alignment = GetDgvAlign(align);
MainDgv.Columns.Add(col);
}
}
}