2017-05-28 13 views
1

編集3:RowTemplate.ContextMenuStripは正常なプログラマが使用するように設計されていないことが明らかになりました。以下に説明するすべての問題に加えて、各行に対して生成されたコンテキストメニューは、元のクローンですが、まではのみです。コンテキストメニューに表示されるではなく、サブメニューにはが表示されます。そして明らかにそれはまたmemory leakを引き起こします。物語のモラル:RowTemplate.ContextMenuStripをこれまで使用しないでください。C#DataGridViewRowのContextMenuStrip:SourceControlに相当するものは何ですか?

だから私は、ユーザーが右DataGridView内の空白部分をクリックしたときに、私は、ユーザーが右DataGridViewの任意の行をクリックしたときに、コンテキストメニューを表示するには、「正しい」方法を考え出したと思ったが、ありません:

Setting ContextMenuStrip for Row

DataGridViewRowTemplateContextMenuStripプロパティを設定することで、私は簡単にDataGridViewの行のそれぞれにコンテキストメニューを添付することができます。しかし、コンテキストメニューを表示するとき、私はを知る必要があります。行が右クリックされています。通常、コンテキストメニューがどこから来るのかを知る方法は、ContextMenuStrip.SourceControlプロパティを使用していますが、この場合は、DataGridViewRowはコントロールではないため、DataGridViewが返されます。だから、どの行が右クリックされているかをどのように知ることができますか?

編集:この方法で行にコンテキストメニューを割り当てると、実際には各行にクローンの同じContextMenuStripが割り当てられていることがわかりました。つまり、それぞれのContextMenuStripTagプロパティを対応するDataGridViewRowに設定することができます。しかし、これが非効率的であるかどうか、これが他の目に見えない問題を引き起こすかどうかはわかりません。

編集2:私はSourceControlプロパティはnullを返し思ったが、それは間違っていた - 私は、元ContextMenuStripSourceControlプロパティをチェックして、開いたContextMenuStripは単にのクローンです。

編集3:質問の先頭を参照してください。

+0

右クリックした行は必ずしも選択された行ではありません。 –

+1

ユーザーが最初にそれを選択しなかったのではありません。 [このコード](https://stackoverflow.com/a/27702246/17034)をオフにして、右クリックで行を選択し、CMSを表示することを検討してください。 –

答えて

0

"CellMouseEnter"で作業します。

{ 
     ... 
     dataGridView1.CellMouseEnter += new DataGridViewCellEventHandler(dataGridView1_CellMouseEnter); 
     menuItem1.Click += new System.EventHandler(this.menuItem1_Click); 
    } 

    void dataGridView1_CellMouseEnter(object sender, DataGridViewCellEventArgs e) 
    { 
     mPoint = dataGridView1.PointToClient(Cursor.Position); 
    } 

    private void menuItem1_Click(object sender, EventArgs e) 
    { 
     DataGridView.HitTestInfo hitTestInfo = dataGridView1.HitTest(mPoint.X, mPoint.Y); 

     Console.WriteLine(hitTestInfo.RowIndex + ", " + hitTestInfo.ColumnIndex); 
    } 
関連する問題