.NET Frameworkフォームのメニュー項目にラジオボタンをふるまわさせる(LINQ使用)
はじめに
フォームのメニューで、ラジオボタン(オプションボタン)的な「排他的チェックマーク付け機能」を簡単に実装をしてみます。チェックボックス的な仕組みは標準で搭載されているのですが...
コードと説明
.NET Framework 4.5.2 で、「Windows フォームアプリケーション」プロジェクトを作成しています。
using System;
using System.Linq;
using System.Windows.Forms;
namespace SampleApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// 初期設定(チェックマークをつけておきます)
// フォームデザイナでプロパティ指定してもよいです。
ToolStripMenuItemViewFontSizeMedium.CheckState = CheckState.Indeterminate;
ToolStripMenuItemViewFontNonBold.CheckState = CheckState.Indeterminate;
}
private void ToolStripMenuItemViewFontSizeLarge_Click(object sender, EventArgs e)
{
CheckToolStripMenuItemAsRadioItem(sender);
}
private void ToolStripMenuItemViewFontSizeMedium_Click(object sender, EventArgs e)
{
CheckToolStripMenuItemAsRadioItem(sender);
}
private void ToolStripMenuItemViewFontSizeSmall_Click(object sender, EventArgs e)
{
CheckToolStripMenuItemAsRadioItem(sender);
}
private void ToolStripMenuItemViewFontSizeExtraSmall_Click(object sender, EventArgs e)
{
CheckToolStripMenuItemAsRadioItem(sender);
}
/// <summary>
/// クリックされたメニュー項目を、同位置にあるメニュー項目をグループとするのラジオボタンとしてチェックします。
/// </summary>
/// <param name="clickedItem"></param>
private void CheckToolStripMenuItemAsRadioItem(object clickedItem)
{
// 選択されたメニュー項目
var thisItem = clickedItem as System.Windows.Forms.ToolStripMenuItem;
if (thisItem == null)
return;
// その親項目
var containerItem = thisItem.GetCurrentParent();
// (Linqを使った例)
// その子項目をToolStripMenuItem型のみ(つまりセパレータなどは除外して)列挙を行い
// 選択された項目であればIntermediate、それ以外はUncheckedを、CheckStateプロパティに設定します。
// 2018-10-20 All()使用でリソース消費を抑えています - albireoさんのコメントより
containerItem.Items.OfType<System.Windows.Forms.ToolStripMenuItem>()
.All(f => { f.CheckState = (f == thisItem) ? CheckState.Indeterminate : CheckState.Unchecked; return true; });
// もとはこちら
// containerItem.Items.OfType<System.Windows.Forms.ToolStripMenuItem>().ToList()
// .ForEach(f => f.CheckState = (f == thisItem) ? CheckState.Indeterminate : CheckState.Unchecked);
}
}
}
CheckToolStripMenuItemAsRadioItem という名のメソッドに集約して、メニューにラジオボタン的ふるまいをさせています。コメントなどを除けば、実質1行にまとめられる内容です。
自分の親の子たちは自分と兄弟姉妹、ということで、「親の子たち」をラジオボタングループのメンバーとみなし、LINQ を使って列挙してチェックマークを設定しています。
対象のメニュー項目をクリックされたイベントハンドラから、前述のこのメソッドを呼び出しています。
クリックされたメニュー項目の「親の子たち」から、 Enumerable.OfType() メソッドでメニュー項目である ToolStripMenuItem 型のもののみ(つまりセパレータなどは除かれます)を列挙し、クリックされた項目であれば CheckState.Intermediate 、そうでなければ CheckState.Unchecked を CheckState プロパティに設定しています。
列挙後の各要素(=メニュー項目)へのプロパティ設定操作は、LINQ の Allメソッドによる評価式内で行わせています(albireoさんのコメントにより改善してみました)
おわりに
LINQ は本当に便利ですね!
あと、ToolStripMenuItem.CheckState プロパティに CheckState.Intermediate を指定して表示される丸点は本来ラジオボタンの選択マークではないのですが、似ているので使ってみています。従来からのWindowsフォームのメニュー項目向けには、CheckMenuRadioItem という、純正ラジオマークを付与する Win32API が用意されているのですよね。。
Author And Source
この問題について(.NET Frameworkフォームのメニュー項目にラジオボタンをふるまわさせる(LINQ使用)), 我々は、より多くの情報をここで見つけました https://qiita.com/otagaisama-1/items/0f2f4472e1bf39483938著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .