- ベストアンサー
C#で右クリックメニューにチェックを入れる方法とは?
- VS2008 のC#でのプログラミングにおいて、右クリックメニューにチェックを入れる方法について教えてください。
- 右クリックメニューには複数の選択肢があり、特定の選択肢を選んだ場合にはさらに別の選択肢が選択可能になる状態を作りたいです。
- また、選択肢のチェックを外す方法をforループでまとめたり、グレーアウト表示をする方法についても教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは。御礼頂きました。 toolStripMenuItem_Clickにおけるsenderの中身が、押されたAAA~EEEのメニュー項目の何れかなので、インデックスを求めるのならば、その中で行います。 //AAA~EEEが押されたら、呼ばれる private void toolStripMenuItem_Click(object sender, EventArgs e) { //senderはAAA~EEEの何れか ToolStripMenuItem clicked = (ToolStripMenuItem)sender; int idx = this.contextMenuStrip1.Items.IndexOf(clicked); } No3の処理の流れを整理しておきます。 (1)Form1_Load内でメニュー項目AAA~EEEにtoolStripMenuItem_Clickを登録。 (2)ボタン1を押す。 (3)button1_Clickが呼ばれる。senderの中身はボタン1なのでメニュー項目とは関係ない。 (4)button1_Click内でコンテキストメニューを表示。 (5)メニュー項目AAA~EEEの何れかを押す。 (6)toolStripMenuItem_Clickが呼ばれる。senderの中身は押されたメニュー項目AAA~EEEの何れか。 (7)toolStripMenuItem_Click内で主題の処理を行う。 と言う事です。
その他の回答 (3)
- machongola
- ベストアンサー率60% (434/720)
こんばんは。御礼頂きました。 private void button1_Click(object sender, EventArgs e) におけるsenderの中身は「押されたボタン」ですので、ToolStripMenuItemではありません。 AAA~EEEのメニューにClickイベントを登録して処理を進めると言った具合です。 例えば、AAA~EEEの中で、BBBが選択されたら、BBBにチェックを入れて、AAA, CCC~EEEからチェックを外しとグレイ化をしたいのでしょうか。 その場合、以下の様になりますが、このまま行くと、上記の例で言えば、AAA, CCC~EEEが2度と押せなくなります(何処か別の場所で、何かをすると、グレイが解除されるならば、此れでも良い)。 private void Form1_Load(object sender, EventArgs e) { //AAA~EEEにクリックイベントを登録 EventHandler click = new EventHandler(this.toolStripMenuItem_Click); int i0 = this.contextMenuStrip1.Items.IndexOf(AAAToolStripMenuItem); int i1 = this.contextMenuStrip1.Items.IndexOf(EEEToolStripMenuItem); for (int i = i0; i <= i1; ++i) { ToolStripMenuItem item = (ToolStripMenuItem)this.contextMenuStrip1.Items[i]; item.Click += click; } } private void button1_Click(object sender, EventArgs e) { this.contextMenuStrip1.Show(Cursor.Position); } //AAA~EEEがクリックされると飛び込んでくる private void toolStripMenuItem_Click(object sender, EventArgs e) { ToolStripMenuItem clicked = (ToolStripMenuItem)sender; int i0 = this.contextMenuStrip1.Items.IndexOf(AAAToolStripMenuItem); int i1 = this.contextMenuStrip1.Items.IndexOf(EEEToolStripMenuItem); for (int i = i0; i <= i1; ++i) { ToolStripMenuItem item = (ToolStripMenuItem)this.contextMenuStrip1.Items[i]; if (item == clicked) { item.Checked = true; item.Enabled = true; } else { item.Checked = false; item.Enabled = false; } } }
お礼
ありがとうございます。動きました!! インデックスの比較ではなく、メニューアイテム同士の比較をするという解決策、ありがとうございます。 私は、 「押されたボタン」sender を対応するメニューアイテムclickedに変換し、 ToolStripMenuItem clicked = (ToolStripMenuItem)sender; メニューアイテムのインデックスを求め、 int idx = contextMenuStrip1.Items.IndexOf(clicked); インデックスの比較をしようとしましたが、 if(i == idx) machongolaさんの方法では、 i番目のメニューアイテム item を求め、 ToolStripMenuItem item = (ToolStripMenuItem)this.contextMenuStrip1.Items[i]; メニューアイテム同士の比較をするんですね。 if (item == clicked) >このまま行くと、上記の例で言えば、AAA, CCC~EEEが2度と押せなくなります(何処か別の場所で、何かをすると、グレイが解除されるならば、此れでも良い)。 ご心配ありがとうございます。実際は、 例えば、AAA~EEEの中で、AAAが選択されたら、AAAにチェックを入れて、BBB~EEEからチェックを外し、ABC,CDE,EFGをグレイ化を解除します。 BBBが選択されたら、BBBにチェックを入れて、AAA, CCC~EEEからチェックを外し、ABC,CDE,EFGをグレイ化します。 つまり、グレーアウトするのは後ろの3つの選択肢 ABC,CDE,EFG です。 AAAからEEEは常に選択可能で、チェックがそのうちの1つに入るということです。 いろいろと教えて頂き、恐縮ですが、向学のためにお聞きします。 「押されたボタン」sender に対応するインデックスを求める方法、ありましたら、ご教授お願いいたします。
- machongola
- ベストアンサー率60% (434/720)
こんにちは。御礼頂きました。 う~む、それで合っていると思います。 AAA <- AAAToolStripMenuItem BBB CCC DDD EEE <- EEEToolStripMenuItem ABC CDE EFG と言う順番に並んでいるのならば、Items.IndexOf()の戻り値として、i0 = 0, i1 = 4になっていないといけません。 private void button1_Click(object sender, EventArgs e) { //ToolStripMenuItem AAAToolStripMenuItem = (ToolStripMenuItem)this.contextMenuStrip1.Items[0]; //ToolStripMenuItem EEEToolStripMenuItem = (ToolStripMenuItem)this.contextMenuStrip1.Items[4]; int i0 = this.contextMenuStrip1.Items.IndexOf(AAAToolStripMenuItem); int i1 = this.contextMenuStrip1.Items.IndexOf(EEEToolStripMenuItem); for (int i = i0; i <= i1; ++i) { ToolStripMenuItem item = (ToolStripMenuItem)this.contextMenuStrip1.Items[i]; item.Checked = false; item.Enabled = false; } //チェックを入れて範囲が崩れていないかを見てみるなど。 //AAAToolStripMenuItem.Checked = true; //EEEToolStripMenuItem.Checked = true; this.contextMenuStrip1.Show(Cursor.Position); }
お礼
ありがとうございます。 お蔭様で、5つだけ消すことが出来ました!! でも、まだつまずいています(悲) 選択したアイテムだけにチェックを入れたいので、 選択したアイテムの番号をidxにいれて、等しければ表示、異なれば非表示にしたいです。 そこで、以下のプログラムを書きましたが、実行時にエラーになります。 int idx = contextMenuStrip1.Items.IndexOf(sender); では、そもそもコンパイルエラーになります。そこで、いったんメニューアイテムmiに代入して添え字を求めることにしましたが、今度は、実行時にエラーになります。 何が悪いのでしょうか? private void button1_Click(object sender, EventArgs e) { ToolStripMenuItem mi = (ToolStripMenuItem)sender; int idx = contextMenuStrip1.Items.IndexOf(mi); int i0 = this.contextMenuStrip1.Items.IndexOf(AAAToolStripMenuItem); int i1 = this.contextMenuStrip1.Items.IndexOf(EEEToolStripMenuItem); for (int i = i0; i <= i1; ++i) { ToolStripMenuItem item = (ToolStripMenuItem)this.contextMenuStrip1.Items[i]; if(i == idx) // 等しいときはチェックを入れる { item.Checked = true; item.Enabled = true; } else { item.Checked = false; item.Enabled = false; } } }
- machongola
- ベストアンサー率60% (434/720)
こんにちは。 contextMenuStrip1.Itemsにメニューアイテムが配列のようになって入っています。 foreachでまとめて処理をするのが手っ取り早いです。 グレイアウトする場合は、 toolStripMenuitem.Enabled = false; で出来ます。 グレイアウトされると、テキスト色が灰色に変化しますが、黒色と見分けづらいので、要注意です。 //アイテムの数だけ回る foreach(ToolStripMenuItem item in this.contextMenuStrip1.Items) { //チェックを外す item.Checked = false; //グレイアウトする item.Enabled = false; }
お礼
回答ありがとうございます。 いろいろ悩んでいて、お礼がおそくなりました。 質問では、私のメニューには AAA,BBB,CCC,DDD,EEE,ABC,CDE,EFG の8つの選択しがあり、そのうち前の5つだけを、チェックを外したりグレーアウトにしたいのです。 教えていただいた方法では8つすべてを一括して処理してしまいます。 そこで、foreach を for (int i = i0; i <= i1; i++) に代え、 int i0 = contextMenuStrip1.Items.IndexOf(AAAToolStripMenuItem); int i1 = contextMenuStrip1.Items.IndexOf(EEEToolStripMenuItem); で範囲設定しようとしましたが、エラーになってしまいうまくいきません
お礼
何度もありがとうございます。 お教えいただいた ToolStripMenuItem clicked = (ToolStripMenuItem)sender; int idx = this.contextMenuStrip1.Items.IndexOf(clicked); をコピペして該当部分に挿入したら、あっさり動きました!! 魔法にかかったようです。 さらに、わかりやすい解説も感謝です。 なんとお礼を言ったらよいのか、感激です。 ありがとうございました。