質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

2回答

3431閲覧

DataGridViewのCellClick関数を通してcontextMenuStripを開くことができない。

yal

総合スコア41

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

0クリップ

投稿2021/09/20 17:36

編集2021/09/21 01:04

前提・実現したいこと

windowsのformアプリをはじめて作成しています。
そのなかでdataGridViewで取得したセルのrowIndexの値を取得して、
contextMenuStripで使いたいのですが、それができません。
よろしくおねがいします。

発生している問題・エラーメッセージ

エラーメッセージはありません。

予期しない動きの原因がわかりました。
dataGridView1_CellClick関数を通っていないことが原因でした。

該当のソースコード

C#

1//前略 2namespace cs_launcher_1 3{ 4 public partial class murrelet : Form 5 { 6 private DataTable dataTable = new DataTable(); 7 int row; 8 9 public murrelet() 10 { 11 InitializeComponent(); 12 13 } 14 15 private void murrelet_Load(object sender, EventArgs e) 16 { 17 this.Text = "murrelet"; 18 using (SQLiteConnection con = new SQLiteConnection("Data Source = test.db")) 19 using (SQLiteDataAdapter adapter = new SQLiteDataAdapter("SELECT * FROM games", con)) 20 { 21 adapter.Fill(dataTable); 22 con.Close(); 23 } 24 } 25 26 void dataGridView1_CellClick(object sender, DataGridViewCellMouseEventArgs e) 27 { 28 string title; 29 string brand; 30 // if (e.ColumnIndex != -1 && e.RowIndex != -1 && e.Button == System.Windows.Forms.MouseButtons.Right) 31 if (e.Button == System.Windows.Forms.MouseButtons.Right) 32 { 33 row = e.RowIndex; 34 //テスト 35 Console.WriteLine(row); 36 } 37 } 38 39//中略 40 41 private void タイトルToolStripMenuItem_Click(object sender, EventArgs e) 42 { 43 string title = (string)dataTable.Rows[row][1]; 44 Clipboard.SetText(title); 45 } 46 } 47}

C#

1//Form1.Designer.cs 2 3//dataGridView1の部分 4 this.dataGridView1.AllowUserToAddRows = false; 5 this.dataGridView1.AllowUserToDeleteRows = false; 6 this.dataGridView1.AllowUserToResizeRows = false; 7 this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 8 this.dataGridView1.ContextMenuStrip = this.contextMenuStrip1; 9 //追加部分 10 this.dataGridView1.Location = new System.Drawing.Point(0, 27); 11 this.dataGridView1.MultiSelect = false; 12 this.dataGridView1.Name = "dataGridView1"; 13 this.dataGridView1.ReadOnly = true; 14 this.dataGridView1.RowTemplate.Height = 21; 15 this.dataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 16 this.dataGridView1.Size = new System.Drawing.Size(802, 401); 17 this.dataGridView1.TabIndex = 0; 18 this.dataGridView1.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellDoubleClick); 19 this.dataGridView1.CellMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dataGridView1_CellClick); 20 21//contextMenuStrip1の部分 22this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 23 this.編集ToolStripMenuItem, 24 this.開くToolStripMenuItem, 25 this.コピーToolStripMenuItem, 26 this.削除ToolStripMenuItem, 27 this.設定ToolStripMenuItem1}); 28 this.contextMenuStrip1.Name = "contextMenuStrip1"; 29 this.contextMenuStrip1.Size = new System.Drawing.Size(126, 114);

試したこと

追記

dataGridView1_CellClick関数内での変数の代入処理の下に
"this.toolStripStatusLabel1.Text = "通った";"と追記しました。
すると表示されていなかったので、関数を通っていないことが原因でした。

dataGridView1_CellClickをどのイベントに対して割り当てていますか。
イベントハンドラがイベントにアタッチされていない。
→CellMouseClickに割り当てられていました。

イベントの選び方が不適切かどうかはわかりませんでした。

イベントが発生していない→左クリックだと発生しています。右クリックで発生しません。

左クリックでは関数を通っているので右クリックだと関数よりcontextMenuStripが優先されているのでしょうか。

補足情報(FW/ツールのバージョンなど)

Windows 10 Home 20H2
VisualStudioVersion = 16.0.31624.102
C#
.NET framework 4.7.2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gentaro

2021/09/20 18:55

せめてコンパイラが出してるエラーメッセージをそのまま質問文に貼るなどしよう。
m.ts10806

2021/09/20 21:30

>発生している問題は数値を変数に代入ができていない点です。 上記「起きてること」ではないです。「思った通り動いてない」だけで「起きている現象」にはなってません。 こういうエラーが出てるとか、Consoleで確認したらこのように出力されるとか そういうことです。デバッグもしてください。 >試したこと そもそもその処理通ってるんでしょうか。
退会済みユーザー

退会済みユーザー

2021/09/20 22:52

開発環境を質問欄に追記してください。OS, Visual Studio のバージョン、.NET Framework / Core のどっちかとそのバージョンなど。 コンパイルは通って実行できるのですか? デバッガを使えますか?
yal

2021/09/20 23:02

なるほど。書き方が主観的すぎました。 もう少し詳しく書きます。すいませんでした。 加えて、エラーは出ていません。 最初にint row;で宣言しているため、既定値の0が入り、 "string title = (string)dataTable.Rows[row][1];"の部分でrowが0であるため 常に1行2列目が呼び出されるという結果になります。 ちなみに他の記述部分でも"string title = (string)dataTable.Rows[row][1];"のような処理を行っており、そこは予想通りの動作をしています。しかし、その処理では変数がその関数内で完結しているため通っていると考えています。そのため、rowがおかしいのではないかと推測しました。 加えて、rowがどのように変化しているか確認しようとした点が試した点の一部でもあります。 dataGridView1_CellClickの関数でrowにdataGridの行の値を代入しようとしていますが、その時点で自分の予想していない動きをしているのか、その後で起きているのかを確認しようと考えました。 そこで、this.tooStripStatusLabel1というラベルに現在のrowの数値を出力しようとしましたが、型キャストができず、(string)をつける方法では"CS0030型'int'を'string'に変換できません"やas式では"CS0039 参照の変換、ボックス変換、アンボックス変換、折り返しの変換、または null 型の変換で、型 'int' を 'string' に変換できません"というものが出てしまい変数rowがどのような動きをしていたのか捕まえることはできませんでした。しかし、試したことに記述があるように変数rowに12などの数値をいれたとしても結果は変わらないので、そこから、dataGridのrowIndexの部分でミスを犯しているわけではないことがエラーの出ていたtooStripStatusLabel1へのrowの出力以外からもわかるため、変数にそもそも代入できていないという推察にいたりました。上記のtooStripStatusLabel1でのエラーは直接的には質問とは関係がないため、わかりやすく明快な質問をしようとしていた手前、記述していませんでした。加えて、本などを読んでC#で作る初めてのプログラムなので変数についての理解がまだ浅いと感じており、変数が自分の予期しない動きをしていると思った次第です。 質問文の方に追記しておきます。 助言ありがとうございます。
yal

2021/09/20 23:04

開発環境についても追記しておきます。教えてくださりありがとうございます。
m.ts10806

2021/09/20 23:17

あの、そこまでコメントに書く余裕があるなら普通に質問本文更新してもらえれば良いのですけど。 そこで過不足があればまた指摘があるでしょうし。 マークダウン使えない、狭い、質問本文のどこと関連性があるのか分かりづらいコメント欄に書かれても承認は得づらいと思います。
yal

2021/09/20 23:22

teratailになれていないため、善は急げということで、 まずコメントで追記のようなものをしていました。質問文にも今書き加えたので、よろしくお願いします。
gentaro

2021/09/20 23:23

適切に改行されてないと読む気が起きない。
退会済みユーザー

退会済みユーザー

2021/09/20 23:49

デバッガを使えますか?
yal

2021/09/20 23:50

VisualStudioのf5のことでしょうか...? 普通に動作しています。
退会済みユーザー

退会済みユーザー

2021/09/21 00:00

デバッガを使えてないようですね。ブレークポイントを設定して、ステップ実行し、変数の内容を調べるという基本的なことができるよう、まずデバッガの使い方をググって調べて勉強してください。 それができないとソフト開発はできないといっても過言ではありません。 こういうサイトでの Q&A でも話が通じにくく、解決に無駄な時間と労力がかかるばかりとなります。
yal

2021/09/21 00:05

そんなことができるんですね。目からウロコです。以後、使っていこうと思います。 しかし、変数が問題というよりは関数のほうが原因だったようです。 お手すきの際に確認よろしくおねがいします。
退会済みユーザー

退会済みユーザー

2021/09/21 00:11 編集

だからデバッガを使って、まず、問題の関数の一行目にブレークポイントをおいて、デバッグ実行して、クリックイベント発生させて、そこで止まるかを調べましょう。話はそれからにしたほうが良さそうです。
退会済みユーザー

退会済みユーザー

2021/09/21 00:15

デバッガを使って調べるのが問題解決にもっとも効果的、それができるのは質問者さんだけということです。
退会済みユーザー

退会済みユーザー

2021/09/21 00:22 編集

ベテランでもプログラムを動かして一発でうまく動くとは限らないので、期待通りに動かないのであれば、まずデバッグします。とりあえずデバッグしましょう。 [超初心者でもわかるデバッグ方法] https://docs.microsoft.com/ja-jp/visualstudio/debugger/debugging-absolute-beginners?view=vs-2019&tabs=csharp [チュートリアル: C# のコードをデバッグする - Visual Studio] https://docs.microsoft.com/ja-jp/visualstudio/get-started/csharp/tutorial-debugger?view=vs-2019
yal

2021/09/21 00:20

一行目にブレークポイントを置きましたが、止まらなかったので、 関数に入っていません。this.toolStripStatusLabel1.Text = "通った";も表示されてなかったので通ってないです。rowの数値も変わっていません。左クリックの方でも試し、止まりました
Daregada

2021/09/21 00:36

dataGridView1_CellClickを、どのイベントに対して割り当てていますか? 実際にデザイナーを表示して、DataGridViewをクリックし、プロパティウィンドウをイベントタブに切り替えて、「dataGridView1_CellClick」が表示されているイベントを教えてください。
退会済みユーザー

退会済みユーザー

2021/09/21 00:40

止まらない=関数が実行されないということで、それでは何ともならないので、止まらない原因を調べてください。想像できるのは (1) そもそものイベントの選び方が不適切、(2) イベントが発生してない、(3) イベントハンドラ(関数)がイベントにアタッチされてない・・・と言ったところです。
退会済みユーザー

退会済みユーザー

2021/09/21 00:49 編集

ここは追記修正依頼欄なので、追加情報等はここに書かなくていいので質問を編集・追記してください。(せいぜい〇〇を追記しました程度の報告でいいです) 困っているのは判りますが、回答者に読みやすい、伝わりやすい質問文を心掛けないと、回答者も情報不足等で答えられません。客観的に、自分の書いた質問文読んで読みやすいと思いますか?あなた自身しか知らない情報が抜けていたりしませんか?(一行目ってどこの一行目?とか)そういう事を考えながら書きましょう。長い打ち消し線の部分は読みづらいので削除していいんじゃないでしょうか。 [質問するときのヒント] https://teratail.com/help/question-tips
yal

2021/09/21 01:05

承知しました。さきほど追記しました。
退会済みユーザー

退会済みユーザー

2021/09/21 01:12

> イベントが発生していない→左クリックだと発生しています。右クリックで発生しません。 やってみましたけど、左右どちらでもイベントは発生しますし、引数 e からクリックされた列のインデックスは取得できます。 何か他の影響を受けているのでは? ContextMenuStrip? それなしでやってみたらどうなりますか?
yal

2021/09/21 01:16

それでした。解決しました。ありがとうございました。
guest

回答2

0

DataGridViewにContextMenuStripプロパティを設定していると、右クリックしてもCellMouseClickイベントが発生しません。

解決策としては、ContextMenuStripプロパティをリセットして(none)に戻し、CellMouseClickイベントの中で右クリックを判定し、自前でメニューを表示します。

その際、メニューの位置をマウスカーソルの位置に合わせないと、画面の左上に表示されてしまいます。

C#

1 private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) 2 { 3 if (e.Button == MouseButtons.Right) { 4 // e.RowIndexを取得してメニューを変更する処理 5 6 // 自前でコンテキストメニューを表示 7 contextMenuStrip1.Show(); 8 contextMenuStrip1.Left = MousePosition.X; 9 contextMenuStrip1.Top = MousePosition.Y; 10 } 11 }

投稿2021/09/21 01:33

編集2021/09/21 02:01
Daregada

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yal

2021/09/21 01:57

ほんとに感謝です。 contextMenuStrip1.Show(e.X,e.Y);とかやって画面左上にしっかり表示させてました。 ありがとうございます!!
guest

0

自己解決

右クリックでショートカットメニューを出すContextMenuStripを設定していると、
右クリックで動く関数を通らずにContextMenuStripを表示するようです。

Form1.Designer.csの
this.dataGridView1.ContextMenuStrip = this.contextMenuStrip1;
この文が不要でした。

ありがとうございました。

投稿2021/09/21 01:20

yal

総合スコア41

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問