C#で右クリックメニューにチェックを入れる方法とは?

このQ&Aのポイント
  • VS2008 のC#でのプログラミングにおいて、右クリックメニューにチェックを入れる方法について教えてください。
  • 右クリックメニューには複数の選択肢があり、特定の選択肢を選んだ場合にはさらに別の選択肢が選択可能になる状態を作りたいです。
  • また、選択肢のチェックを外す方法をforループでまとめたり、グレーアウト表示をする方法についても教えてください。
回答を見る
  • ベストアンサー

C# 右クリックメニューにチェックを入れたい

VS2008 のC#でのプログラミングです。 右クリックメニューに、 AAA,BBB,CCC,DDD,EEE,ABC,CDE,EFG という選択肢があり、 AAA,BBB,CCC,DDD,EEE,の中の1つだけが選べ、 AAAを選んだときだけ、 さらに、ABC,CDE,EFGの1つが選択できる状態を作りたいと思っています。 つまり、 AAAを選んだとき、AAAにチェックを入れ、BBB,CCC,DDD,EEEのチェックを外し、 ABC,CDE,EFGを選択可能にする。 BBB,CCC,DDD,EEEを選んだとき、選んだ以外のAAA,・・EEEのチェックを外し、 ABC,CDE,EFGを選択不可のグレーアウト表示にする。 を実現したいです。 contextMenuStripを選択して右クリックメニューを作り、選択肢をつくるところまではできました。 もちろん、各処理先で、 AAAToolStripMenuItem.Checked = true; BBBToolStripMenuItem.Checked = false; CCCToolStripMenuItem.Checked = false; DDDToolStripMenuItem.Checked = false; EEEToolStripMenuItem.Checked = false; や AAAToolStripMenuItem.Checked = false; BBBToolStripMenuItem.Checked = true; CCCToolStripMenuItem.Checked = false; DDDToolStripMenuItem.Checked = false; EEEToolStripMenuItem.Checked = false; のように、それぞれ他のチェックを外し、自分をチェックするコードを書けばよいのはわかりますが、 「他のチェックを外す」をforループでまとめて書きたいのですが書き方がわかりません。またグレーアウトする方法も合わせて教えて下さい。 昔、Cで作成したときは、  EnableMenuItem(hMenu, i, MF_ENABLED/MF_GRAYED); で選択可能・グレーアウト  CheckMenuItem(hMenu, i, MF_CHECKED/MF_UNCHECKED); でチェックのオンオフができましたが、VS2008のC#でのやり方がわかりません。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.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内で主題の処理を行う。  と言う事です。

usatan2
質問者

お礼

何度もありがとうございます。 お教えいただいた ToolStripMenuItem clicked = (ToolStripMenuItem)sender; int idx = this.contextMenuStrip1.Items.IndexOf(clicked); をコピペして該当部分に挿入したら、あっさり動きました!! 魔法にかかったようです。 さらに、わかりやすい解説も感謝です。 なんとお礼を言ったらよいのか、感激です。 ありがとうございました。

その他の回答 (3)

回答No.3

 こんばんは。御礼頂きました。  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; } } }

usatan2
質問者

お礼

ありがとうございます。動きました!! インデックスの比較ではなく、メニューアイテム同士の比較をするという解決策、ありがとうございます。 私は、 「押されたボタン」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 に対応するインデックスを求める方法、ありましたら、ご教授お願いいたします。

回答No.2

 こんにちは。御礼頂きました。  う~む、それで合っていると思います。 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); }

usatan2
質問者

お礼

ありがとうございます。 お蔭様で、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;   }  } }

回答No.1

 こんにちは。  contextMenuStrip1.Itemsにメニューアイテムが配列のようになって入っています。  foreachでまとめて処理をするのが手っ取り早いです。  グレイアウトする場合は、  toolStripMenuitem.Enabled = false;  で出来ます。  グレイアウトされると、テキスト色が灰色に変化しますが、黒色と見分けづらいので、要注意です。 //アイテムの数だけ回る foreach(ToolStripMenuItem item in this.contextMenuStrip1.Items) { //チェックを外す item.Checked = false; //グレイアウトする item.Enabled = false; }

usatan2
質問者

お礼

回答ありがとうございます。 いろいろ悩んでいて、お礼がおそくなりました。 質問では、私のメニューには 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); で範囲設定しようとしましたが、エラーになってしまいうまくいきません

関連するQ&A

  • CSVに外部テキストファイルを列として追加する方法

    こんにちは。 CSVファイル(base.csv)の先頭列に、別のテキストファイル(add.txt)の中身を新規の列として挿入したいと考えているのですが、よい方法がわかりません。。。 どうのような方法を使えば対応することができるでしょうか? どうぞよろしくお願いいたします。 ■CSVファイル(master.csv) title,developer_name,seller_name,primary_genre_name,application_url AAA,BBB,CCC,DDD,EEE AAA,BBB,CCC,DDD,EEE AAA,BBB,CCC,DDD,EEE AAA,BBB,CCC,DDD,EEE ■テキストファイル(add.txt) id 000 111 222 333 ↓ ■目標としたファイル(master.csv) id,title,developer_name,seller_name,primary_genre_name,application_url 000,AAA,BBB,CCC,DDD,EEE 111,AAA,BBB,CCC,DDD,EEE 222,AAA,BBB,CCC,DDD,EEE 333,AAA,BBB,CCC,DDD,EEE

  • awkやsed等で特定の文字間を抜き出す

    cat text aaaa bbbb <AAA> ccc ddd <BBB> eee とあるときに <AAA> ccc ddd <BBB> だけ抜き出したいです。 どのようにすればよいでしょうか?

  • SQLについて

    aaa bbb ccc ddd eee ggg hhh ---------------------------------------------- 111 111 111 111 111 111 111 112 112 112 112 112 112 111 112 113 113 113 113 113 111 114 114 114 114 114 114 111 114 114 114 114 114 114 112 114 115 115 114 114 115 111 114 115 115 114 114 115 112 116 116 116 116 116 116 111 116 116 116 116 116 116 112 116 116 116 116 116 117 111 116 116 116 116 116 117 112 118 118 118 118 118 118 118 上記のようなデータより、SQLのSELECTを使用して、以下のように抽出したいです。 抽出条件は以下が全て満たしているものとなります。 ・aaa,ccc,ddd,eee,gggが重複、hhhが小さいもの ・bbbが異なるもの aaa bbb ccc ddd eee ggg hhh ---------------------------------------------- 112 112 112 112 112 112 111 ・・・(1) 112 113 113 113 113 113 111 ・・・(1) 114 114 114 114 114 114 111 ・・・(2) 114 115 114 114 114 115 111 ・・・(2) (1)はaaa,ccc,ddd,eee,gggが重複、bbbが異なるため抽出対象 (2)はaaa,ccc,ddd,eee,gggが重複、bbbが異なるため抽出対象  また、hhhが小さいもの 以上、よろしくお願いします。

  • SQL文を教えてください。

    すみません、SQLを教えてください。 ID, 名前の2つのフィールドを持つテーブルがあります。 中身は以下のように入っています。 1, AAA 2. AAA 2, BBB 3, CCC 3, AAA 4, DDD 5, EEE, 5, DDD これを、名前のダブリをスキップしながら、 IDの大きな順番に名前を取り出したいのです。 結果は、以下のようになればいいです。 DDD EEE AAA CCC BBB どのようなSQLを組んだら実現できますか? よろしくお願いいたします。

  • 抽出して並べ替えたい

    初めまして 非常に悩んでいます。 エクセルシートの列に下記のようにデータが並んでいます。(文字列) AAA bbb ccc (空白) BBB ddd eee (空白) AAA bbb ccc (空白) AAA eee ggg 並べ替え後 AAA AAA BBB bbb eee ddd ccc ggg eee 尚、列上でセル位置は任意で、空白行も任意です。(1つ以上です) できれば関数でお願いします。 VBAの場合、使用したことがないので詳しくお願いします。

  • テキストデータに書いてある文字(行)をシャッフルしたい秀丸エディタなど

    テキストデータにある文字をシャッフルする方法はありますか? 例えば、 aaa bbb ccc ddd eee を eee bbb aaa ddd ccc のような感じでもともと順番にあった行を変えてシャッフルみたいな感じに したいです。 秀丸エディタやさくらエディタでこのようなことは出来ますでしょうか?

  • エクセルで列にあるユニークなデータの個数が知りたい

    おはようございます。 エクセルでA列に以下のようなデータがあるとします。 この中で何種類のデータがあるのかを知りたいのです。 この場合は、AAA,BBB,CCC,DDD,EEEの5種類なので5という答えが欲しいのです。 ただし、A列に入るデータは非常に多岐(800種類以上)に渡ります。 また、印刷を前提としてるためソートなどはできません。 さらに1枚のシートにこのようなデータがいくつかあるので、その決まった範囲内で個数を抽出する必要があります。 なにとぞ皆様のお知恵をお貸しくださいませ。 よろしくお願いします。 AAA AAA BBB CCC AAA DDD DDD BBB DDD DDD EEE EEE

  • 異なるテーブルのレコード削除

    オラクル初心者です。宜しくお願いします。 AAA、BBB、CCCというテーブルがあると仮定します。 画面から入力された値(ddd)をキーとして、CCCテーブルから該当するレコードをセレクト文で引っ張り、eeeという値を抜き出したとします。 そのeeeという値をキーにAAA、BBBテーブルのレコードを削除するにはどういうSQLを発行すればよろしいでしょうか? "delete from AAA, BBB where eee = (select eee from CCC where fff = ddd);" では駄目でした。 質問が下手でわかりにくいかもしれませんが、どうかご教授お願いします。

  • C言語のプログラム

    文字列が与えられ、その中の最初に現れた文字"@"から最後の"@"の部分を画面に表示する関数ponkan[]を教えてください。 よろしくお願いします。 (例 変換前 aaa@bbb@ccc@ddd@eee 変換後 bbb@ccc@ddd@ #include <stdio.h> int main(void) { ... return (0); }

  • SQL文の書き方

    SQL文の書き方を教えて下さい。 以下の2つのクエリー(1のクエリー&2のクエリー)を1つのクエリーで1度に抽出をかけたいのですがSQL文の書き方がわかりません。 データの発生条件としては TableBのField1は必ずTableAのField1に存在するという条件です。 TableAのField1が「AAA」から「EEE」まである場合は、TableBのField1も必ず「AAA」から「EEE」の範囲内で発生します。 よろしくお願い致します。 1のクエリー ---------------------------------------------------------------- TableA Field1 ---------------------------------------------------------------- AAA AAA AAA BBB BBB CCC DDD DDD EEE EEE EEE ---------------------------------------------------------------- Field1をサマライズしてカウントと名称を取得するクエリー Select Count(TableA.Field1) as RecCount, TableA.Field1 From TableA 結果 RecCount  Field1 3      AAA 2      BBB 1      CCC 2      DDD 3      EEE ---------------------------------------------------------------- 2のクエリー ---------------------------------------------------------------- TableB Field1 ---------------------------------------------------------------- BBB CCC CCC EEE ---------------------------------------------------------------- Field1をサマライズしてカウントと名称を取得するクエリー Select Count(TableB.Field1) as RecCount, TableB.Field1 From TableB 結果 RecCount  Field1 1      BBB 2      CCC 1      EEE ---------------------------------------------------------------- 希望する結果 TableAのRecCount TableBのRecCount TableAのField1 3                   AAA 2         1         BBB 1         2         CCC 2                   DDD 3         1         EEE

専門家に質問してみよう