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 { /// /// Poiメインフォーム /// 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; /// /// コンストラクタ /// 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(); } /// /// フォームロード時 /// /// /// /// 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); } /// /// フォーム閉じるとき /// /// /// /// 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()); } /// /// デフォルトのメニュー項目(表示設定など)を作成 /// 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() .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); } /// /// 余白調整パネルメニュー作成 /// /// 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; } /// /// 親メニュー開くときに追加する処理 /// /// /// 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; } /// /// メニュー項目追加 /// /// /// /// /// /// protected ToolStripMenuItem AddCheckMenuItem( int index, string text, string name, bool defaultValue, Action 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; } } /// /// 列追加 /// /// /// /// 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); } } }