[C#] ContextMenuStrip を呼び出したセルの特定

このQ&Aのポイント
  • DataGridViewのどのセルを右クリックしてポップアップメニュー(ContextMenuStrip)が表示されたか知りたいです。
  • popup.SourceControlを用いると、DataGridViewコントロールしか返ってこないため、DataGridViewのCellMouseEventハンドラを実装する必要がある。
  • DataGridViewのセルで右クリックされた場合に、それがどのセルか特定する解決方法は他にはないのか
回答を見る
  • ベストアンサー

[C#] ContextMenuStrip を呼び出したセルの特定

DataGridViewのどのセルを右クリックしてポップアップメニュー(ContextMenuStrip) が表示されたか知りたいのですが using System; using System.Windows.Forms; public class MyForm : Form { DataGridView dgv; DataGridViewTextBoxColumn dgvColumn1; FileDialog fileDlg; ContextMenuStrip popup; ToolStripMenuItem popupItem; public MyForm() { dgv = new DataGridView(); dgvColumn1 = new DataGridViewTextBoxColumn(); fileDlg = new OpenFileDialog(); popup = new ContextMenuStrip(); popupItem = new ToolStripMenuItem(); dgvColumn1.HeaderText = "column1"; dgvColumn1.ContextMenuStrip = popup; dgv.Dock = DockStyle.Fill; dgv.RowTemplate.Height = 16; dgv.Columns.Add(dgvColumn1); popupItem.Text = "file"; popupItem.MouseUp += delegate(object sender, MouseEventArgs e) { if (fileDlg.ShowDialog() == DialogResult.OK) { //右クリックしたセル.Text = filedlg.FileName; } }; // popup menu popup.Items.Add(popupItem); Controls.Add(dgv); } } 上のソースにて、 http://dobon.net/vb/dotnet/control/cmsourcecontrol.html にあるように、popup.SourceControlを用いても、DataGridView コントロールしか返って来ません。 となると、DataGridViewのCellMouseEventハンドラを実装する必要が出てくると思うのですがこれ以外解決方法ってないですかね・・?

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

  • ベストアンサー
  • koala17
  • ベストアンサー率39% (15/38)
回答No.1

ContextMenuStripの位置(Left,Top)からDataGridViewのHitTestで求められると思います。 フォームのクライアント領域のサイズや親コントロールと位置などを考慮して、正しい座標を計算する必要はありますが・・・

関連するQ&A

  • VS C# のコンテキストの動作について

    VS C# のコンテキストの動作がうまくいきません、助けてください>< List Viewのアイテムを右クリックしたときに「アイテム名を表示させる」というコンテキストを表示し、それをクリックするとアイテム名を表示させるというプログラムを組んだのですが、一度目はうまく動作するのですが、その後、List Viewのアイテムのない場所を右クリックしてもコンテキストが表示されてしまいます。 何が原因なんでしょうか? 教えてください、お願いします。 以下コード 前略 private void ListView_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { ConTextMenu(); } } private void ConTextMenu() { ContextMenuStrip cms = new ContextMenuStrip(); ToolStripMenuItem menu1 = new ToolStripMenuItem(); menu1.Text = "アイテム名を表示させる"; cms.Items.AddRange(new ToolStripMenuItem[] { menu1} ); menu1.Click += new EventHandler(menu_Click); this.ContextMenuStrip = cms; } private void menu_Click(object sender, EventArgs e) { string msg = sender.ToString(); if (msg == "アイテム名を表示させる") { ListViewItem item1 = new ListViewItem(); item1 = songlist.SelectedItems[0]; iname = item1.SubItems[0].Text; MessageBox.show(iname.Tostring()); }

  • DataGridViewの列スタイルについて

    開発環境  VB.NET  SQLServer2008 DataGridViewにDBから取得したデータを一覧表示させようと思っています。 テキストボックスの列、チェックボックス、コンボボックスの列を 追加させることはできたのですが、同一列に異なる種類のコントロールを 配置するということはできるのでしょうか? 例えば・・・ -------------- 行No |列1 -------------- 1   |□ -------------- 2   |□▼ -------------- ・行No1、列1のセルはチェックボックスのセルを表示する ・行No2、列1のセルはコンボボックスのセルを表示する 列を追加しているコードは以下の通りです。 Form_Load時に実行しています。 ------------------------------------------------------------- Private Sub initializeDgvTest() Dim dgv As DataGridView = Me.dgvTest dgv.Columns.Clear() dgv.AutoGenerateColumns = False Dim colLabel As New DataGridViewTextBoxColumn() colLabel.DataPropertyName = "LABEL" colLabel.Name = "LABEL" colLabel.HeaderText = "ラベル" dgv.Columns.Add(colLabel) Dim colVal As New DataGridViewCheckBoxColumn() colVal .DataPropertyName = "VALUE" colVal .Name = "VALUE" colVal .HeaderText = "値" dgv.Columns.Add(colVal ) End Sub ※データのバインドについて  DataTableをDataGridViewのDataSourceに設定しています。 ------------------------------------------------------------- 上記のコードでいうと、 「VALUE」列のコントロールの種類をセル単位で変更しようとしています。 何かいい方法がありましたら、アドバイスよろしくお願いします。 以上です。

  • コンテキストメニュークリック時のイベントハンドラ

    C#にてフォームアプリを作成しています。 そこでツリービューに表示されたノードを右クリックしたときにコンテキストメニューが表示される ように下記のように記述しました。表示されたノードの上で右クリックすると「Export」、「Import」 というメニューが表示されます。 しかし、イベントハンドラの書き方がよくわかりません。 「Export」又は「Import」がクリックされたというイベントはどう検出すればよいでしょうか。 // ノード右クリック時の動作 private void treeView1_MouseDown(object sender, MouseEventArgs e) { // 右クリックでもノードを選択させる if (e.Button == MouseButtons.Right) { // ノードの選択 treeView1.SelectedNode = treeView1.GetNodeAt(e.X, e.Y); // コンテクストメニューの作成 ContextMenuStrip contextMenu = new ContextMenuStrip(); ToolStripMenuItem openLabel = new ToolStripMenuItem(); openLabel.Text = "Export"; ToolStripMenuItem deleteLabel = new ToolStripMenuItem(); deleteLabel.Text = "Import"; contextMenu.Items.Add(openLabel); contextMenu.Items.Add(deleteLabel); // ツリービューにコンテキストメニューを追加 treeView1.ContextMenuStrip = contextMenu; } }

  • C# 2010 contextMenuStripのファンクション名の不

    C# 2010 contextMenuStripのファンクション名の不思議? まず2ケのメニューアイテムを持つcontextMenuStripを作り、それぞれのTEXTを試験1、試験3と改名します ダブルクリックするとハンドラーが出来て、その名称が(1)(2)のように TEXT名+ToolStripMenuItem_Click なります ここでいったんプロジェクトを終了して再ロードします 画像のように試験1と試験3の間に『試験3を途中に追加』を入れてダブルクリックして作ったファンクション名は前2者とは異なり (3)の如くtoolStripMenuItem1_Click となってしまいます なぜ 試験2を途中に追加ToolStripMenuItem_Click にならないのでしょうか? private void 試験1ToolStripMenuItem_Click(object sender, EventArgs e) --- (1) { } private void 試験3ToolStripMenuItem_Click(object sender, EventArgs e) --- (2) { } private void toolStripMenuItem1_Click(object sender, EventArgs e) --- (3) { } 追伸 『試験3を途中に追加』が長すぎるかと思い、『試験3』だけにしても結果は同じでした

  • C# csvをexcelシートのように No.2

    VS2017でC#を独学しています。 https://okwave.jp/qa/q9340465.html 上記で質問したように、Tabcontrolの中にタブページごとにdatagridview表を挿入し、 そこにCSVファイルを表示させたいと思っています。 今、このような形で動きますが、あってますでしょうか? 下記コードの回りくどい部分や、おかしい部分など教えていただけるとうれしいです。 よろしくお願いします。 private System.Windows.Forms.DataGridView dg; private TabPage tabPage9; private void button3_Click(object sender, EventArgs e) { tabPage9 = new TabPage(); tabPage9.Text = "Tab" + i; tabControl1.TabPages.Add(tabPage9); // 追加したタブページにdatagridviewを追加する。 this.dg = new System.Windows.Forms.DataGridView(); this.dg.Name = "dg"; tabPage9.Controls.Add(dg); this.dg.Dock = DockStyle.Fill; this.dg.Columns.Add("", "No"); this.dg.Columns.Add("", "Name"); this.dg.Rows.Add(3); this.dg[0, 0].Value = "aaa"; this.dg[0, 1].Value = "bbb"; i++; }

  • C#のDataGridViwのセル単位の設定

    C#のDataGridViewは、セル単位で書式やセルのスタイルを指定することはできますか? たとえば、セル(1,1)はボタンのスタイル、セル(2,1)はテキストボックスのスタイルで背景色は黄色、などです。 Grapecityのスプレッドだと、デザイナで開いてセル単位の設定ができるのですが、DatagridViewはそういう設定ってできたでしょうか。 そもそも、DataGridViewは列単位で設定し、その設定の行をたくさん生成するコントロールだと思うのですが、同じ列でも1行目と2行目で設定を変えたいのです。 DataGridViewを継承したカスタムコントロールを作って、セルのプロパティを実装するとかも厳しいですよね…(書いてる自分は無理じゃないかと思っています…)

  • C# 動的に読み込んだコントロールの削除

    C#にて動的に読み込んだ不特定多数のコントロールを削除する正しい手順は どのような物でしょうか。 MSDNによるとコンテナに読み込んだコントロールをFlowLayoutPanel.Clear()で クリアするとメモリリークにつながるため、Dispose()をしろとあります。 動的に作成したコントロールが不特定多数のため、Foreach文をつかい FlowLayoutPanel.Controlsで確認できた物をDispose()しましたが、偶数indexの コントロールしか削除されませんでした。 まぁ、これはなんとなく分かるのですが、では、正しくすべてのコントロールを 削除するにはどうしたら良いのか分かりません。 ご教示のほど、よろしくお願いいたします。 確認コード(空のForm1_Loadに貼り付け) ※現象を再現させるためのサンプルで意味はありません // コントロール配置用のコンテナ FlowLayoutPanel panel = new FlowLayoutPanel(); panel.Dock = System.Windows.Forms.DockStyle.Fill; this.Controls.Add(panel); // テストコントロール追加ボタン Button create = new Button(); create.Size = new Size(50, 25); create.Text = "create"; create.Click += (ss, ee) => { for (int i = 0; i < 100; i++) { TextBox text = new TextBox(); text.Size = new Size(50, 25); text.Text = i.ToString(); panel.Controls.Add(text); } }; panel.Controls.Add(create); // コントロール削除ボタン Button delete = new Button(); delete.Size = new Size(50, 25); delete.Text = "delete"; delete.Click += (ss, ee) => { foreach (var control in panel.Controls) { if (control is TextBox) { ((TextBox)control).Dispose(); } } }; panel.Controls.Add(delete);

  • DataGridViewのセルのItem設定につい

    DataGridView内にコンボボックスのカラムを設定しました。 下記のサイトを参考にしました。 http://dobon.net/vb/dotnet/datagridview/comboboxdropdownstyle.html 入力した内容をカラム単位ではなく、セル単位で追加したかったため、 CellValidatingメソッドを下記の通り一部変更しました。 //CellValidatingイベントハンドラ private void DataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) { DataGridView dgv = (DataGridView)sender; //該当する列か調べる if (dgv.Columns[e.ColumnIndex].Name == "sComboColumn" && dgv.Columns[e.ColumnIndex] is DataGridViewComboBoxColumn) { //DataGridViewComboBoxColumn cbc = // (DataGridViewComboBoxColumn)dgv.Columns[e.ColumnIndex]; // // ↓cellへ変更 // DataGridViewComboBoxCell cbc = (DataGridViewComboBoxCell)dgv.Rows[e.RowIndex].Cells[e.ColumnIndex]; //コンボボックスの項目に追加する if (!cbc.Items.Contains(e.FormattedValue)) { cbc.Items.Add(e.FormattedValue); } //セルの値を設定しないと、元に戻ってしまう dgv[e.ColumnIndex, e.RowIndex].Value = e.FormattedValue; } } コンボボックスに入力し、EnterやTabを押したタイミングでコンボボックスのリストに、 入力した文字列が追加されます。また、入力した文字列がセルに表示された状態になります。 しかし、その後同じセルに文字列を入力した場合、リストに文字列が追加されますが、 セルに表示される文字列はその前に入力された文字列のままです。 どのようにすれば入力後のセルの内容を設定できるかご存じの方がいれば ご教授いただきたいです。

  • C# イベント登録(RowPostPaint) delegate

    C#でデータグリッドビューにイベントを登録しようとしているのですが 方法が分からず困っています。 どこかのホームページで以下のように dgv.RowPostPaint += delegate { } までは良いのですが、中身を以下のように eオブジェクトを使うとエラーになります。 どうすれば、eが使えるのでしょうか? 根本から分かっていないので、すみませんがそこからよろしくお願いいたします。 DataGridView dgv = new DataGridView(); dgv.RowPostPaint += delegate { // 行ヘッダのセル領域を、行番号を描画する長方形とする // (ただし右端に4ドットのすき間を空ける) Rectangle rect = new Rectangle( e.RowBounds.Location.X, e.RowBounds.Location.Y, dgv.RowHeadersWidth - 4, e.RowBounds.Height); // 上記の長方形内に行番号を縦方向中央&右詰めで描画する // フォントや前景色は行ヘッダの既定値を使用する TextRenderer.DrawText( e.Graphics, (e.RowIndex + 0).ToString(), dgv.RowHeadersDefaultCellStyle.Font, rect, dgv.RowHeadersDefaultCellStyle.ForeColor, TextFormatFlags.VerticalCenter | TextFormatFlags.Right); };

  • C# Form間のデータの受け渡し

    Form2のテキストボックスとコンボボックス内のテキストをForm1のdataGridViewに転記したいと思っているのですがうまくいかず悩んでいます. //datagridveiwに添付 DataGridView f1_Text = (DataGridView)f1.Controls["dataGridView1"]; f1_Text.Rows.Add(Text1, Text2, "→", Text3, Text4); 上記のようなプログラムを組んで走らせると下記のようなエラーとなってしまいます. NullReferenceException オブジェクト参照がオブジェクト インスタンスに設定されていません。 Text1~Text2はそれぞれテキストボックスとコンボボックスのテキストになります. どなたか,どうすればよいかご教授頂けませんでしょうか?

専門家に質問してみよう